* Re: [PATCH 4/4] ARM: dts: mxs: add oled support for the cfa-10036
From: Maxime Ripard @ 2012-08-29 13:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120823144541.GL24242@S2101-09.ap.freescale.net>
Hi,
Le 23/08/2012 16:45, Shawn Guo a écrit :
> On Thu, Aug 23, 2012 at 10:42:31AM +0200, Maxime Ripard wrote:
>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> Cc: Brian Lilly <brian@crystalfontz.com>
>> ---
>> arch/arm/boot/dts/imx28-cfa10036.dts | 20 ++++++++++++++++++++
>> 1 file changed, 20 insertions(+)
>>
> Looks mostly good, but I have to postpone it until driver part gets
> accepted.
Yes, I totally understand that.
Florian, are you ok with merging the fb driver in the first patch?
> Some minor comments below.
Ok, I'll send an update with the next version of the patchset if there
is comments on the driver, or alone if the driver is merged as is.
Maxime
--
Maxime Ripard, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 00/19] SH Mobile LCDC panel cleanup (including board code)
From: Laurent Pinchart @ 2012-08-29 14:58 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1345122054-16013-1-git-send-email-laurent.pinchart@ideasonboard.com>
Hi Simon,
On Wednesday 29 August 2012 15:07:49 Simon Horman wrote:
> On Mon, Aug 27, 2012 at 05:35:46PM +0200, Laurent Pinchart wrote:
> > On Monday 27 August 2012 17:54:52 Simon Horman wrote:
> > > On Thu, Aug 16, 2012 at 03:00:35PM +0200, Laurent Pinchart wrote:
> > > > Hi everybody,
> > > >
> > > > As part of a general panel API implementation (more on that a bit
> > > > later), I've cleaned up panel support in the LCDC driver and in the
> > > > related board code. The result is 19 patches independent of the
> > > > generic panel API that I would like to get reviewed by the respective
> > > > board maintainers.
> > >
> > > Hi Paul,
> > >
> > > I'm happy for you to take all of this, including the mach-shmobile
> > > portions through your tree if that works for you.
> >
> > I usually push the LCDC patches through the fbdev tree. I'm fine with both
> > options though.
>
> I'm happy for you to handle things in your normal way.
>
> I guess that means that once the LCDC changes are in the fbdev tree
> Paul should take the linux-sh changes and I should take the shmobile
> changes, is that correct?
To avoid bisection breakages all the patches should go through the same tree.
This will of course increase the chances of merge conflicts. Would you rather
take them all through linux-sh ?
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH 6/9] ARM: OMAP1: move omap1_bl pdata out of arch/arm/*
From: Tomi Valkeinen @ 2012-08-29 15:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1346195937-6383-7-git-send-email-grinberg@compulab.co.il>
[-- Attachment #1: Type: text/plain, Size: 4396 bytes --]
On Wed, 2012-08-29 at 02:18 +0300, Igor Grinberg wrote:
> omap1 backlight platform data resides inside plat/board.h while it
> should be inside include/linux/...
> Move the omap1 backlight platform data to
> include/linux/platform_data/.
>
> Cc: Richard Purdie <rpurdie@rpsys.net>
> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
> Cc: linux-fbdev@vger.kernel.org
> Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
> ---
> arch/arm/mach-omap1/board-osk.c | 1 +
> arch/arm/mach-omap1/board-palmte.c | 1 +
> arch/arm/mach-omap1/board-palmtt.c | 1 +
> arch/arm/mach-omap1/board-palmz71.c | 1 +
> arch/arm/plat-omap/include/plat/board.h | 7 -------
> drivers/video/backlight/omap1_bl.c | 2 +-
> include/linux/platform_data/omap1_bl.h | 11 +++++++++++
> 7 files changed, 16 insertions(+), 8 deletions(-)
> create mode 100644 include/linux/platform_data/omap1_bl.h
>
> diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
> index 8784705..569b687 100644
> --- a/arch/arm/mach-omap1/board-osk.c
> +++ b/arch/arm/mach-omap1/board-osk.c
> @@ -39,6 +39,7 @@
> #include <linux/mtd/partitions.h>
> #include <linux/mtd/physmap.h>
> #include <linux/i2c/tps65010.h>
> +#include <linux/platform_data/omap1_bl.h>
>
> #include <asm/mach-types.h>
> #include <asm/mach/arch.h>
> diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
> index 26bcb9d..7bf00ba 100644
> --- a/arch/arm/mach-omap1/board-palmte.c
> +++ b/arch/arm/mach-omap1/board-palmte.c
> @@ -28,6 +28,7 @@
> #include <linux/interrupt.h>
> #include <linux/apm-emulation.h>
> #include <linux/omapfb.h>
> +#include <linux/platform_data/omap1_bl.h>
>
> #include <asm/mach-types.h>
> #include <asm/mach/arch.h>
> diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
> index 4d09944..2cce505 100644
> --- a/arch/arm/mach-omap1/board-palmtt.c
> +++ b/arch/arm/mach-omap1/board-palmtt.c
> @@ -27,6 +27,7 @@
> #include <linux/omapfb.h>
> #include <linux/spi/spi.h>
> #include <linux/spi/ads7846.h>
> +#include <linux/platform_data/omap1_bl.h>
>
> #include <asm/mach-types.h>
> #include <asm/mach/arch.h>
> diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
> index 3559803..45ab9f0 100644
> --- a/arch/arm/mach-omap1/board-palmz71.c
> +++ b/arch/arm/mach-omap1/board-palmz71.c
> @@ -30,6 +30,7 @@
> #include <linux/omapfb.h>
> #include <linux/spi/spi.h>
> #include <linux/spi/ads7846.h>
> +#include <linux/platform_data/omap1_bl.h>
>
> #include <asm/mach-types.h>
> #include <asm/mach/arch.h>
> diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h
> index 5938c72..d0bc46e 100644
> --- a/arch/arm/plat-omap/include/plat/board.h
> +++ b/arch/arm/plat-omap/include/plat/board.h
> @@ -19,13 +19,6 @@ struct omap_lcd_config {
> u8 data_lines;
> };
>
> -struct device;
> -struct fb_info;
> -struct omap_backlight_config {
> - int default_intensity;
> - int (*set_power)(struct device *dev, int state);
> -};
> -
> /* for TI reference platforms sharing the same debug card */
> extern int debug_card_init(u32 addr, unsigned gpio);
>
> diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
> index bfdc5fb..92257ef 100644
> --- a/drivers/video/backlight/omap1_bl.c
> +++ b/drivers/video/backlight/omap1_bl.c
> @@ -27,9 +27,9 @@
> #include <linux/fb.h>
> #include <linux/backlight.h>
> #include <linux/slab.h>
> +#include <linux/platform_data/omap1_bl.h>
>
> #include <mach/hardware.h>
> -#include <plat/board.h>
> #include <plat/mux.h>
>
> #define OMAPBL_MAX_INTENSITY 0xff
> diff --git a/include/linux/platform_data/omap1_bl.h b/include/linux/platform_data/omap1_bl.h
> new file mode 100644
> index 0000000..881a8e9
> --- /dev/null
> +++ b/include/linux/platform_data/omap1_bl.h
> @@ -0,0 +1,11 @@
> +#ifndef __OMAP1_BL_H__
> +#define __OMAP1_BL_H__
> +
> +#include <linux/device.h>
You could use struct device; here.
> +
> +struct omap_backlight_config {
> + int default_intensity;
> + int (*set_power)(struct device *dev, int state);
> +};
> +
> +#endif
Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 6/9] ARM: OMAP1: move omap1_bl pdata out of arch/arm/*
From: Igor Grinberg @ 2012-08-29 21:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1346252664.12380.0.camel@deskari>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 08/29/12 18:04, Tomi Valkeinen wrote:
> On Wed, 2012-08-29 at 02:18 +0300, Igor Grinberg wrote:
>> omap1 backlight platform data resides inside plat/board.h while it
>> should be inside include/linux/...
>> Move the omap1 backlight platform data to
>> include/linux/platform_data/.
>>
>> Cc: Richard Purdie <rpurdie@rpsys.net>
>> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
>> Cc: linux-fbdev@vger.kernel.org
>> Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
>> ---
>> arch/arm/mach-omap1/board-osk.c | 1 +
>> arch/arm/mach-omap1/board-palmte.c | 1 +
>> arch/arm/mach-omap1/board-palmtt.c | 1 +
>> arch/arm/mach-omap1/board-palmz71.c | 1 +
>> arch/arm/plat-omap/include/plat/board.h | 7 -------
>> drivers/video/backlight/omap1_bl.c | 2 +-
>> include/linux/platform_data/omap1_bl.h | 11 +++++++++++
>> 7 files changed, 16 insertions(+), 8 deletions(-)
>> create mode 100644 include/linux/platform_data/omap1_bl.h
[...]
>> diff --git a/include/linux/platform_data/omap1_bl.h b/include/linux/platform_data/omap1_bl.h
>> new file mode 100644
>> index 0000000..881a8e9
>> --- /dev/null
>> +++ b/include/linux/platform_data/omap1_bl.h
>> @@ -0,0 +1,11 @@
>> +#ifndef __OMAP1_BL_H__
>> +#define __OMAP1_BL_H__
>> +
>> +#include <linux/device.h>
>
> You could use struct device; here.
Yes I know, but I don't think it is any better.
>
>> +
>> +struct omap_backlight_config {
>> + int default_intensity;
>> + int (*set_power)(struct device *dev, int state);
>> +};
>> +
>> +#endif
>
> Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Thanks!
- --
Regards,
Igor.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJQPozJAAoJEBDE8YO64EfasmQP/2v38LY4t30rnl3jOvs6vvsa
RPFFQG1lxkFTpMHMkOvb4pW/k00IHxkcv2hRrGmoBWbEJqel7b0LyEFVV+M+uCSo
nCVsnd/Pu7jftCwC2Ggy2PBE16n+9I6UttN4Vsh7a8f2qwtXdOxL01xxyM7cVtn4
YQRhyVrKMiiKhNfKtvQV2V0npsVVksgnKm0K1zNRiZkTuKjZ4sJrliGYaU6B5F32
MHx31U0r1VbxZwOi9m19Ucyuf1CYvVKhlmeMop1fE4+3Dkt1708pMWOpK9iknMQU
m5cA+25a7YolDIluvfXlH+7hDFZixDUd5pFeJA0llaqOv2PSHGT0kYDOTmtRyKvD
D3mq22amwPlqgjXdxJMS5gckF6N3KrBjA3AHW4FpoTQjdCciiql3k+DMaRNM6Dzm
WjCCZBOQHy5dSRn6HzNo2iSP+B8mANh8eoJJAoyS3JJ+ihf4hiV1PEC9jXxWTg1H
M449feGQccXUfYj8pTlXtTXEk8L5x3kBlU9VMMzlA1kQN0VoFOQRhSl+UVdu2ckA
SPotVgiUCUzT9x1xEoIBjrz+kLAk0bYvRv2vUflzzH8lf+/MYz4UxDikSCsifpF1
s/5evCRgSUokm1VxlFEMLiUG0gb8FJR3TylJU4CD5U9dbkel2urKoE1zfc4LyPRT
ycdLeCP+C7ZcsaNApWMS
=kElj
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
From: Tony Lindgren @ 2012-08-30 0:20 UTC (permalink / raw)
To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, paul, linux-omap, linux-fbdev
In-Reply-To: <cover.1345468541.git.cmahapatra@ti.com>
* Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
>
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch removes cpu_is checks from VENC code.
> The 5th patch disables VENC support on OMAP4.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.
Good to see this, we need this badly to avoid blocking
single zImage effort on omaps. Can you also please take
a look at the omap dss headers and make sure that
drivers/video/omap code does not do any #include <mach/*.h>
or <plat/*.h>?
The driver specific headers should be now moved to live in
include/linux/platform_data directory instead of the current
arch/arm/*omap*/include/*.
Regards,
Tony
^ permalink raw reply
* Re: [PATCH 1/4] video: mmp display subsystem
From: Jingoo Han @ 2012-08-30 1:37 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1346234684-12532-1-git-send-email-zzhu3@marvell.com>
On Wednesday, August 29, 2012 7:05 PM Zhou Zhu wrote:
>
> Added mmp display subsystem to support Marvell MMP display controllers.
>
> This subsystem contains 4 parts:
> --fb folder
> --core.c
> --hw folder
> --panel folder
>
> 1. fb folder contains implementation of fb.
> fb get path and ovly from common interface and operates on these structures.
>
> 2. core.c provides common interface for a hardware abstraction.
> Major parts of this interface are:
> a) Path: path is a output device connected to a panel or HDMI TV.
> Main operations of the path is set/get timing/output color.
> fb operates output device through path structure.
> b) Ovly: Ovly is a buffer shown on the path.
> Ovly describes frame buffer and its source/destination size, offset, input
> color, buffer address, z-order, and so on.
> Each fb device maps to one ovly.
>
> 3. hw folder contains implementation of hardware operations defined by core.c.
> It registers paths for fb use.
>
> 4. panel folder contains implementation of panels.
> It's connected to path. Panel drivers would also regiester panels and linked
> to path when probe.
>
> Change-Id: I830e34af9aad3196c2db021b4fb90ceeafbf73d2
Please remove unnecessary 'Change-Id'.
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Lisa Du <cldu@marvell.com>
> ---
> drivers/video/Kconfig | 1 +
> drivers/video/Makefile | 1 +
> drivers/video/mmp/Kconfig | 5 +
> drivers/video/mmp/Makefile | 1 +
> drivers/video/mmp/core.c | 217 +++++++++++++++++++++++++
> include/video/mmp_disp.h | 381 ++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 606 insertions(+), 0 deletions(-)
> create mode 100644 drivers/video/mmp/Kconfig
> create mode 100644 drivers/video/mmp/Makefile
> create mode 100644 drivers/video/mmp/core.c
> create mode 100644 include/video/mmp_disp.h
>
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 0217f74..b71a5c9 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -2447,6 +2447,7 @@ config FB_PUV3_UNIGFX
> source "drivers/video/omap/Kconfig"
> source "drivers/video/omap2/Kconfig"
> source "drivers/video/exynos/Kconfig"
> +source "drivers/video/mmp/Kconfig"
> source "drivers/video/backlight/Kconfig"
>
> if VT
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index ee8dafb..6b0ae31 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -106,6 +106,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
> obj-$(CONFIG_FB_PXA) += pxafb.o
> obj-$(CONFIG_FB_PXA168) += pxa168fb.o
> obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
> +obj-$(CONFIG_MMP_DISP) += mmp/
> obj-$(CONFIG_FB_W100) += w100fb.o
> obj-$(CONFIG_FB_TMIO) += tmiofb.o
> obj-$(CONFIG_FB_AU1100) += au1100fb.o
> diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig
> new file mode 100644
> index 0000000..0554336
> --- /dev/null
> +++ b/drivers/video/mmp/Kconfig
> @@ -0,0 +1,5 @@
> +menuconfig MMP_DISP
> + tristate "Marvell MMP Display Subsystem support"
> + depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
> + help
> + Marvell Display Subsystem support.
> diff --git a/drivers/video/mmp/Makefile b/drivers/video/mmp/Makefile
> new file mode 100644
> index 0000000..820eb10
> --- /dev/null
> +++ b/drivers/video/mmp/Makefile
> @@ -0,0 +1 @@
> +obj-y += core.o
> diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
> new file mode 100644
> index 0000000..b2e7433
> --- /dev/null
> +++ b/drivers/video/mmp/core.c
> @@ -0,0 +1,217 @@
> +/*
> + * linux/drivers/video/mmp/common.c
> + * This driver is a common framework for Marvell Display Controller
> + *
> + * Copyright (C) 2012 Marvell Technology Group Ltd.
> + * Authors: Zhou Zhu <zzhu3@marvell.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * 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/slab.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/export.h>
> +#include <video/mmp_disp.h>
> +
> +static struct mmp_ovly *path_get_ovly(struct mmp_path *path,
> + int ovly_id)
> +{
> + if (path && ovly_id < path->ovly_num)
> + return &path->ovlys[ovly_id];
> + return 0;
> +}
> +
> +static int path_check_status(struct mmp_path *path)
> +{
> + int i;
> + for (i = 0; i < path->ovly_num; i++)
> + if (path->ovlys[i].status)
> + return 1;
> +
> + return 0;
> +}
> +
> +/*
> + * Get modelist write pointer of modelist.
> + * It also returns modelist number
> + * this function fetches modelist from phy/panel:
> + * for HDMI/parallel or dsi to hdmi cases, get from phy
> + * or get from panel
> + */
> +static int path_get_modelist(struct mmp_path *path,
> + struct mmp_mode **modelist)
> +{
> + BUG_ON(!path || !modelist);
> +
> + if (path->panel && path->panel->get_modelist)
> + return path->panel->get_modelist(path->panel, modelist);
> +
> + return 0;
> +}
> +
> +#define list_find(_item, _list, _field, _name) \
> + do {\
> + int found = 0;\
> + list_for_each_entry(_item, &_list, node) {\
> + dev_dbg(_item->dev, "checking %s, target %s",\
> + _item->_field, _name);\
> + if (strcmp(_name, _item->_field) = 0) {\
> + found = 1;\
> + break;\
> + } \
> + } \
> + if (!found)\
> + _item = NULL;\
> + } while (0);
It makes checkpatch warning as below.
WARNING: do {} while (0) macros should not be semicolon terminated
Please remove semicolon as below.
} while (0)
> +
> +/*
> + * panel list is used to pair panel/path when path/panel registered
> + * path list is used for both buffer driver and platdriver
> + * plat driver do path register/unregister
> + * panel driver do panel register/unregister
> + * buffer driver get registered path
> + */
> +static LIST_HEAD(panel_list);
> +static LIST_HEAD(path_list);
> +static DEFINE_MUTEX(disp_lock);
> +
> +int mmp_register_panel(struct mmp_panel *panel)
> +{
> + struct mmp_path *path;
> +
> + mutex_lock(&disp_lock);
> +
> + /* add */
> + list_add_tail(&panel->node, &panel_list);
> +
> + /* try to register to path */
> + list_find(path, path_list, name, panel->plat_path_name);
> + if (path) {
> + dev_info(panel->dev, "register to path %s\n",
> + panel->plat_path_name);
> + path->panel = panel;
> + }
> +
> + mutex_unlock(&disp_lock);
> + return 1;
> +}
> +EXPORT_SYMBOL_GPL(mmp_register_panel);
> +
> +void mmp_unregister_panel(struct mmp_panel *panel)
> +{
> + mutex_lock(&disp_lock);
> + list_del(&panel->node);
> + mutex_unlock(&disp_lock);
> +}
> +EXPORT_SYMBOL_GPL(mmp_unregister_panel);
> +
> +struct mmp_path *mmp_get_path(const char *name)
> +{
> + struct mmp_path *path;
> +
> + mutex_lock(&disp_lock);
> + list_find(path, path_list, name, name);
> + mutex_unlock(&disp_lock);
> +
> + return path;
> +}
> +EXPORT_SYMBOL_GPL(mmp_get_path);
> +
> +struct mmp_path *mmp_register_path(struct mmp_path_info *info)
> +{
> + int i, size;
> + struct mmp_path *path = NULL;
> + struct mmp_panel *panel;
> +
> + size = sizeof(struct mmp_path)
> + + sizeof(struct mmp_ovly) * info->ovly_num;
> + path = kzalloc(size, GFP_KERNEL);
> + if (!path)
> + goto failed;
> +
> + /* path set */
> + path->ovlys = (void *)path + sizeof(struct mmp_path);
> + mutex_init(&path->access_ok);
> + path->dev = info->dev;
> + path->id = info->id;
> + path->name = info->name;
> + path->output_type = info->output_type;
> + path->ovly_num = info->ovly_num;
> + path->plat_data = info->plat_data;
> + path->ops.set_mode = info->set_mode;
> +
> + mutex_lock(&disp_lock);
> + /* get panel */
> + list_find(panel, panel_list, plat_path_name, info->name);
> + if (panel) {
> + dev_info(path->dev, "get panel %s\n", panel->name);
> + path->panel = panel;
> + }
> +
> + dev_info(path->dev, "register %s, ovly_num %d\n",
> + path->name, path->ovly_num);
> +
> + /* default op set: if already set by driver, never cover it */
> + if (!path->ops.check_status)
> + path->ops.check_status = path_check_status;
> + if (!path->ops.get_ovly)
> + path->ops.get_ovly = path_get_ovly;
> + if (!path->ops.get_modelist)
> + path->ops.get_modelist = path_get_modelist;
> +
> + /* step3: init ovlys */
> + for (i = 0; i < path->ovly_num; i++) {
> + path->ovlys[i].path = path;
> + path->ovlys[i].id = i;
> + mutex_init(&path->ovlys[i].access_ok);
> + path->ovlys[i].ops = info->ovly_ops;
> + }
> +
> + /* add to pathlist */
> + list_add_tail(&path->node, &path_list);
> +
> + mutex_unlock(&disp_lock);
> + return path;
> +
> +failed:
> + kfree(path);
> + mutex_unlock(&disp_lock);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(mmp_register_path);
> +
> +void mmp_unregister_path(struct mmp_path *path)
> +{
> + int i;
> +
> + if (!path)
> + return;
> +
> + mutex_lock(&disp_lock);
> + /* del from pathlist */
> + list_del(&path->node);
> +
> + /* deinit ovlys */
> + for (i = 0; i < path->ovly_num; i++)
> + mutex_destroy(&path->ovlys[i].access_ok);
> +
> + mutex_destroy(&path->access_ok);
> +
> + kfree(path);
> + mutex_unlock(&disp_lock);
> +
> + dev_info(path->dev, "de-register %s\n", path->name);
> +}
> +EXPORT_SYMBOL_GPL(mmp_unregister_path);
> diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
> new file mode 100644
> index 0000000..e7318f9
> --- /dev/null
> +++ b/include/video/mmp_disp.h
> @@ -0,0 +1,381 @@
> +/*
> + * linux/include/video/mmp_disp.h
> + * Header file for Marvell MMP Display Controller
> + *
> + * Copyright (C) 2012 Marvell Technology Group Ltd.
> + * Authors: Zhou Zhu <zzhu3@marvell.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * 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/>.
> + *
> + */
> +
> +#ifndef _MMP_DISP_H_
> +#define _MMP_DISP_H_
> +#include <linux/kthread.h>
> +
> +enum {
> + PIXFMT_UYVY = 0,
> + PIXFMT_VYUY,
> + PIXFMT_YUYV,
> + PIXFMT_YUV422P,
> + PIXFMT_YVU422P,
> + PIXFMT_YUV420P,
> + PIXFMT_YVU420P,
> + PIXFMT_RGB565 = 0x100,
> + PIXFMT_BGR565,
> + PIXFMT_RGB1555,
> + PIXFMT_BGR1555,
> + PIXFMT_RGB888PACK,
> + PIXFMT_BGR888PACK,
> + PIXFMT_RGB888UNPACK,
> + PIXFMT_BGR888UNPACK,
> + PIXFMT_RGBA888,
> + PIXFMT_BGRA888,
> + PIXFMT_RGB666, /* for output usage */
> + PIXFMT_PSEUDOCOLOR = 0x200,
> +};
> +
> +static inline int pixfmt_to_stride(int pix_fmt)
> +{
> + switch (pix_fmt) {
> + case PIXFMT_RGB565:
> + case PIXFMT_BGR565:
> + case PIXFMT_RGB1555:
> + case PIXFMT_BGR1555:
> + case PIXFMT_UYVY:
> + case PIXFMT_VYUY:
> + case PIXFMT_YUYV:
> + return 2;
> + case PIXFMT_RGB888UNPACK:
> + case PIXFMT_BGR888UNPACK:
> + case PIXFMT_RGBA888:
> + case PIXFMT_BGRA888:
> + return 4;
> + case PIXFMT_RGB888PACK:
> + case PIXFMT_BGR888PACK:
> + return 3;
> + case PIXFMT_YUV422P:
> + case PIXFMT_YVU422P:
> + case PIXFMT_YUV420P:
> + case PIXFMT_YVU420P:
> + case PIXFMT_PSEUDOCOLOR:
> + return 1;
> + default:
> + return 0;
> + }
> +}
> +
> +/* parameters used by path/ovly */
> +/* ovly related para: win/addr */
> +struct mmp_win {
> + /* position/size of window */
> + u16 xsrc;
> + u16 ysrc;
> + u16 xdst;
> + u16 ydst;
> + u16 xpos;
> + u16 ypos;
> + u16 left_crop;
> + u16 right_crop;
> + u16 up_crop;
> + u16 bottom_crop;
> + int pix_fmt;
> +};
> +
> +struct mmp_addr {
> + /* phys address */
> + u32 phys[6];
> +};
> +
> +/* path related para: mode */
> +struct mmp_mode {
> + const char *name;
> + u32 refresh;
> + u32 xres;
> + u32 yres;
> + u32 left_margin;
> + u32 right_margin;
> + u32 upper_margin;
> + u32 lower_margin;
> + u32 hsync_len;
> + u32 vsync_len;
> + u32 hsync_invert;
> + u32 vsync_invert;
> + u32 invert_pixclock;
> + u32 pixclock_freq;
> + int pix_fmt_out;
> +};
> +
> +/* main structures */
> +struct mmp_path;
> +struct mmp_ovly;
> +struct mmp_panel;
> +
> +
Please remove unnecessary line.
> +/* status types */
> +enum {
> + mmp_OFF = 0,
> + mmp_ON,
> +};
> +
> +static inline const char *stat_name(int stat)
> +{
> + switch (stat) {
> + case mmp_OFF:
> + return "OFF";
> + case mmp_ON:
> + return "ON";
> + default:
> + return "UNKNOWNSTAT";
> + }
> +}
> +
> +struct mmp_ovly_ops {
> + /* should be provided by driver */
> + void (*set_fetch)(struct mmp_ovly *ovly, int fetch_id);
> + void (*set_onoff)(struct mmp_ovly *ovly, int status);
> + void (*set_win)(struct mmp_ovly *ovly, struct mmp_win *win);
> + int (*set_addr)(struct mmp_ovly *ovly, struct mmp_addr *addr);
> +};
> +
> +/* ovly describes a z-order indexed slot in each path. */
> +struct mmp_ovly {
> + int id;
> + const char *name;
> + struct mmp_path *path;
> +
> + /* ovly info: private data */
> + int dmafetch_id;
> + struct mmp_addr addr;
> + struct mmp_win win;
> +
> + /* state */
> + int open_count;
> + int status;
> + struct mutex access_ok;
> +
> + struct mmp_ovly_ops *ops;
> +};
> +
> +/* panel type */
> +enum {
> + PANELTYPE_Active = 0,
> + PANELTYPE_Smart,
> + PANELTYPE_TV,
> + PANELTYPE_DSI_CMD,
> + PANELTYPE_DSI_VIDEO,
> +};
> +
> +enum {
> + PANEL_CMDS_SPI,
> + PANEL_CMDS_DSI,
> +};
> +
> +/* commands for panel: commands and sleep time in ms */
> +struct mmp_panel_cmds {
> + u16 *cmds;
> + int cmds_num;
> + int sleep;
> +};
> +
> +struct mmp_spi_cfg {
> + u32 clk_cnt;
> + u32 rx_bits;
> + u32 tx_bits;
> + u32 wire_num;
> +};
> +
> +struct mmp_panel_cmd_sets {
> + int type;
> + struct mmp_panel_cmds *on_cmds;
> + int on_cmds_num;
> + struct mmp_panel_cmds *off_cmds;
> + int off_cmds_num;
> + void *config;
> +};
> +
> +struct mmp_panel {
> + /* use node to register to list */
> + struct list_head node;
> + const char *name;
> + /* path name used to connect to proper path configed */
> + const char *plat_path_name;
> + struct device *dev;
> + int panel_type;
> + int (*get_modelist)(struct mmp_panel *panel,
> + struct mmp_mode **modelist);
> + void (*set_mode)(struct mmp_panel *panel,
> + struct mmp_mode *mode);
> + void (*plat_set_onoff)(int status);
> + struct mmp_panel_cmd_sets *cmd_set;
> + /* todo: add query */
> +};
> +
> +struct mmp_path_ops {
> + int (*check_status)(struct mmp_path *path);
> + struct mmp_ovly *(*get_ovly)(struct mmp_path *path,
> + int ovly_id);
> + int (*get_modelist)(struct mmp_path *path,
> + struct mmp_mode **modelist);
> +
> + /* follow ops should be provided by driver */
> + void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
> + void (*set_onoff)(struct mmp_path *path, int status);
> + /* todo: add query */
> +};
> +
> +/* path output types */
> +enum {
> + PATH_OUT_PARALLEL,
> + PATH_OUT_DSI,
> + PATH_OUT_HDMI,
> +};
> +
> +/* path is main part of mmp-disp */
> +struct mmp_path {
> + /* use node to register to list */
> + struct list_head node;
> +
> + /* init data */
> + struct device *dev;
> +
> + int id;
> + const char *name;
> + int output_type;
> + struct mmp_panel *panel;
> + void *plat_data;
> +
> + /* dynamic use */
> + struct mmp_mode mode;
> +
> + /* state */
> + int open_count;
> + int status;
> + struct mutex access_ok;
> +
> + struct mmp_path_ops ops;
> +
> + /* layers */
> + int ovly_num;
> + struct mmp_ovly *ovlys;
> +};
> +
> +extern struct mmp_path *mmp_get_path(const char *name);
> +static inline void mmp_path_set_mode(struct mmp_path *path,
> + struct mmp_mode *mode)
> +{
> + if (path)
> + path->ops.set_mode(path, mode);
> +}
> +static inline void mmp_path_set_onoff(struct mmp_path *path, int status)
> +{
> + if (path)
> + path->ops.set_onoff(path, status);
> +}
> +static inline int mmp_path_get_modelist(struct mmp_path *path,
> + struct mmp_mode **modelist)
> +{
> + if (path)
> + return path->ops.get_modelist(path, modelist);
> + return 0;
> +}
> +static inline struct mmp_ovly *mmp_path_get_ovly(
> + struct mmp_path *path, int ovly_id)
> +{
> + if (path)
> + return path->ops.get_ovly(path, ovly_id);
> + return NULL;
> +}
> +static inline void mmp_ovly_set_fetch(struct mmp_ovly *ovly,
> + int fetch_id)
> +{
> + if (ovly)
> + ovly->ops->set_fetch(ovly, fetch_id);
> +}
> +static inline void mmp_ovly_set_onoff(struct mmp_ovly *ovly, int status)
> +{
> + if (ovly)
> + ovly->ops->set_onoff(ovly, status);
> +}
> +static inline void mmp_ovly_set_win(struct mmp_ovly *ovly,
> + struct mmp_win *win)
> +{
> + if (ovly)
> + ovly->ops->set_win(ovly, win);
> +}
> +static inline int mmp_ovly_set_addr(struct mmp_ovly *ovly,
> + struct mmp_addr *addr)
> +{
> + if (ovly)
> + return ovly->ops->set_addr(ovly, addr);
> + return 0;
> +}
> +
> +/*
> + * driver data is set from each detailed ctrl driver for path usage
> + * it defined a common interface that plat driver need to implement
> + */
> +struct mmp_path_info {
> + /* driver data, set when registed*/
> + const char *name;
> + struct device *dev;
> + int id;
> + int output_type;
> + int ovly_num;
> + void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
> + void (*set_onoff)(struct mmp_path *path, int status);
> + struct mmp_ovly_ops *ovly_ops;
> + void *plat_data;
> +};
> +
> +extern struct mmp_path *mmp_register_path(
> + struct mmp_path_info *info);
> +extern void mmp_unregister_path(struct mmp_path *path);
> +extern int mmp_register_panel(struct mmp_panel *panel);
> +extern void mmp_unregister_panel(struct mmp_panel *panel);
> +
> +/* defintions for platform data */
> +/* interface for buffer driver */
> +struct mmp_buffer_driver_mach_info {
> + const char *name;
> + const char *path_name;
> + int ovly_id;
> + int dmafetch_id;
> + int default_pixfmt;
> + u32 irq_mask;
> +};
> +
> +/* interface for controllers driver */
> +struct mmp_mach_path_config {
> + const char *name;
> + int ovly_num;
> + int output_type;
> + u32 path_config;
> + u32 link_config;
> +};
> +
> +struct mmp_mach_plat_info {
> + const char *name;
> + const char *clk_name;
> + int path_num;
> + struct mmp_mach_path_config *paths;
> +};
> +
> +/* interface for panel drivers */
> +struct mmp_mach_panel_info {
> + const char *name;
> + void (*plat_set_onoff)(int status);
> + const char *plat_path_name;
> +};
> +#endif /* _MMP_DISP_H_ */
> --
> 1.7.0.4
>
> --
> 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
* [PATCHv2 1/4] video: mmp display subsystem
From: Zhou Zhu @ 2012-08-30 2:20 UTC (permalink / raw)
To: linux-fbdev
Added mmp display subsystem to support Marvell MMP display controllers.
This subsystem contains 4 parts:
--fb folder
--core.c
--hw folder
--panel folder
1. fb folder contains implementation of fb.
fb get path and ovly from common interface and operates on these structures.
2. core.c provides common interface for a hardware abstraction.
Major parts of this interface are:
a) Path: path is a output device connected to a panel or HDMI TV.
Main operations of the path is set/get timing/output color.
fb operates output device through path structure.
b) Ovly: Ovly is a buffer shown on the path.
Ovly describes frame buffer and its source/destination size, offset, input
color, buffer address, z-order, and so on.
Each fb device maps to one ovly.
3. hw folder contains implementation of hardware operations defined by core.c.
It registers paths for fb use.
4. panel folder contains implementation of panels.
It's connected to path. Panel drivers would also regiester panels and linked
to path when probe.
Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
Signed-off-by: Lisa Du <cldu@marvell.com>
---
drivers/video/Kconfig | 1 +
drivers/video/Makefile | 1 +
drivers/video/mmp/Kconfig | 5 +
drivers/video/mmp/Makefile | 1 +
drivers/video/mmp/core.c | 217 +++++++++++++++++++++++++
include/video/mmp_disp.h | 380 ++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 605 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/mmp/Kconfig
create mode 100644 drivers/video/mmp/Makefile
create mode 100644 drivers/video/mmp/core.c
create mode 100644 include/video/mmp_disp.h
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0217f74..b71a5c9 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2447,6 +2447,7 @@ config FB_PUV3_UNIGFX
source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
source "drivers/video/exynos/Kconfig"
+source "drivers/video/mmp/Kconfig"
source "drivers/video/backlight/Kconfig"
if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ee8dafb..6b0ae31 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_PXA168) += pxa168fb.o
obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
+obj-$(CONFIG_MMP_DISP) += mmp/
obj-$(CONFIG_FB_W100) += w100fb.o
obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig
new file mode 100644
index 0000000..0554336
--- /dev/null
+++ b/drivers/video/mmp/Kconfig
@@ -0,0 +1,5 @@
+menuconfig MMP_DISP
+ tristate "Marvell MMP Display Subsystem support"
+ depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
+ help
+ Marvell Display Subsystem support.
diff --git a/drivers/video/mmp/Makefile b/drivers/video/mmp/Makefile
new file mode 100644
index 0000000..820eb10
--- /dev/null
+++ b/drivers/video/mmp/Makefile
@@ -0,0 +1 @@
+obj-y += core.o
diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
new file mode 100644
index 0000000..51e2e62
--- /dev/null
+++ b/drivers/video/mmp/core.c
@@ -0,0 +1,217 @@
+/*
+ * linux/drivers/video/mmp/common.c
+ * This driver is a common framework for Marvell Display Controller
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/export.h>
+#include <video/mmp_disp.h>
+
+static struct mmp_ovly *path_get_ovly(struct mmp_path *path,
+ int ovly_id)
+{
+ if (path && ovly_id < path->ovly_num)
+ return &path->ovlys[ovly_id];
+ return 0;
+}
+
+static int path_check_status(struct mmp_path *path)
+{
+ int i;
+ for (i = 0; i < path->ovly_num; i++)
+ if (path->ovlys[i].status)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Get modelist write pointer of modelist.
+ * It also returns modelist number
+ * this function fetches modelist from phy/panel:
+ * for HDMI/parallel or dsi to hdmi cases, get from phy
+ * or get from panel
+ */
+static int path_get_modelist(struct mmp_path *path,
+ struct mmp_mode **modelist)
+{
+ BUG_ON(!path || !modelist);
+
+ if (path->panel && path->panel->get_modelist)
+ return path->panel->get_modelist(path->panel, modelist);
+
+ return 0;
+}
+
+#define list_find(_item, _list, _field, _name)\
+ do {\
+ int found = 0;\
+ list_for_each_entry(_item, &_list, node) {\
+ dev_dbg(_item->dev, "checking %s, target %s",\
+ _item->_field, _name);\
+ if (strcmp(_name, _item->_field) = 0) {\
+ found = 1;\
+ break;\
+ } \
+ } \
+ if (!found)\
+ _item = NULL;\
+ } while (0)
+
+/*
+ * panel list is used to pair panel/path when path/panel registered
+ * path list is used for both buffer driver and platdriver
+ * plat driver do path register/unregister
+ * panel driver do panel register/unregister
+ * buffer driver get registered path
+ */
+static LIST_HEAD(panel_list);
+static LIST_HEAD(path_list);
+static DEFINE_MUTEX(disp_lock);
+
+int mmp_register_panel(struct mmp_panel *panel)
+{
+ struct mmp_path *path;
+
+ mutex_lock(&disp_lock);
+
+ /* add */
+ list_add_tail(&panel->node, &panel_list);
+
+ /* try to register to path */
+ list_find(path, path_list, name, panel->plat_path_name);
+ if (path) {
+ dev_info(panel->dev, "register to path %s\n",
+ panel->plat_path_name);
+ path->panel = panel;
+ }
+
+ mutex_unlock(&disp_lock);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(mmp_register_panel);
+
+void mmp_unregister_panel(struct mmp_panel *panel)
+{
+ mutex_lock(&disp_lock);
+ list_del(&panel->node);
+ mutex_unlock(&disp_lock);
+}
+EXPORT_SYMBOL_GPL(mmp_unregister_panel);
+
+struct mmp_path *mmp_get_path(const char *name)
+{
+ struct mmp_path *path;
+
+ mutex_lock(&disp_lock);
+ list_find(path, path_list, name, name);
+ mutex_unlock(&disp_lock);
+
+ return path;
+}
+EXPORT_SYMBOL_GPL(mmp_get_path);
+
+struct mmp_path *mmp_register_path(struct mmp_path_info *info)
+{
+ int i, size;
+ struct mmp_path *path = NULL;
+ struct mmp_panel *panel;
+
+ size = sizeof(struct mmp_path)
+ + sizeof(struct mmp_ovly) * info->ovly_num;
+ path = kzalloc(size, GFP_KERNEL);
+ if (!path)
+ goto failed;
+
+ /* path set */
+ path->ovlys = (void *)path + sizeof(struct mmp_path);
+ mutex_init(&path->access_ok);
+ path->dev = info->dev;
+ path->id = info->id;
+ path->name = info->name;
+ path->output_type = info->output_type;
+ path->ovly_num = info->ovly_num;
+ path->plat_data = info->plat_data;
+ path->ops.set_mode = info->set_mode;
+
+ mutex_lock(&disp_lock);
+ /* get panel */
+ list_find(panel, panel_list, plat_path_name, info->name);
+ if (panel) {
+ dev_info(path->dev, "get panel %s\n", panel->name);
+ path->panel = panel;
+ }
+
+ dev_info(path->dev, "register %s, ovly_num %d\n",
+ path->name, path->ovly_num);
+
+ /* default op set: if already set by driver, never cover it */
+ if (!path->ops.check_status)
+ path->ops.check_status = path_check_status;
+ if (!path->ops.get_ovly)
+ path->ops.get_ovly = path_get_ovly;
+ if (!path->ops.get_modelist)
+ path->ops.get_modelist = path_get_modelist;
+
+ /* step3: init ovlys */
+ for (i = 0; i < path->ovly_num; i++) {
+ path->ovlys[i].path = path;
+ path->ovlys[i].id = i;
+ mutex_init(&path->ovlys[i].access_ok);
+ path->ovlys[i].ops = info->ovly_ops;
+ }
+
+ /* add to pathlist */
+ list_add_tail(&path->node, &path_list);
+
+ mutex_unlock(&disp_lock);
+ return path;
+
+failed:
+ kfree(path);
+ mutex_unlock(&disp_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mmp_register_path);
+
+void mmp_unregister_path(struct mmp_path *path)
+{
+ int i;
+
+ if (!path)
+ return;
+
+ mutex_lock(&disp_lock);
+ /* del from pathlist */
+ list_del(&path->node);
+
+ /* deinit ovlys */
+ for (i = 0; i < path->ovly_num; i++)
+ mutex_destroy(&path->ovlys[i].access_ok);
+
+ mutex_destroy(&path->access_ok);
+
+ kfree(path);
+ mutex_unlock(&disp_lock);
+
+ dev_info(path->dev, "de-register %s\n", path->name);
+}
+EXPORT_SYMBOL_GPL(mmp_unregister_path);
diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
new file mode 100644
index 0000000..1905a9b
--- /dev/null
+++ b/include/video/mmp_disp.h
@@ -0,0 +1,380 @@
+/*
+ * linux/include/video/mmp_disp.h
+ * Header file for Marvell MMP Display Controller
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Authors: Zhou Zhu <zzhu3@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/>.
+ *
+ */
+
+#ifndef _MMP_DISP_H_
+#define _MMP_DISP_H_
+#include <linux/kthread.h>
+
+enum {
+ PIXFMT_UYVY = 0,
+ PIXFMT_VYUY,
+ PIXFMT_YUYV,
+ PIXFMT_YUV422P,
+ PIXFMT_YVU422P,
+ PIXFMT_YUV420P,
+ PIXFMT_YVU420P,
+ PIXFMT_RGB565 = 0x100,
+ PIXFMT_BGR565,
+ PIXFMT_RGB1555,
+ PIXFMT_BGR1555,
+ PIXFMT_RGB888PACK,
+ PIXFMT_BGR888PACK,
+ PIXFMT_RGB888UNPACK,
+ PIXFMT_BGR888UNPACK,
+ PIXFMT_RGBA888,
+ PIXFMT_BGRA888,
+ PIXFMT_RGB666, /* for output usage */
+ PIXFMT_PSEUDOCOLOR = 0x200,
+};
+
+static inline int pixfmt_to_stride(int pix_fmt)
+{
+ switch (pix_fmt) {
+ case PIXFMT_RGB565:
+ case PIXFMT_BGR565:
+ case PIXFMT_RGB1555:
+ case PIXFMT_BGR1555:
+ case PIXFMT_UYVY:
+ case PIXFMT_VYUY:
+ case PIXFMT_YUYV:
+ return 2;
+ case PIXFMT_RGB888UNPACK:
+ case PIXFMT_BGR888UNPACK:
+ case PIXFMT_RGBA888:
+ case PIXFMT_BGRA888:
+ return 4;
+ case PIXFMT_RGB888PACK:
+ case PIXFMT_BGR888PACK:
+ return 3;
+ case PIXFMT_YUV422P:
+ case PIXFMT_YVU422P:
+ case PIXFMT_YUV420P:
+ case PIXFMT_YVU420P:
+ case PIXFMT_PSEUDOCOLOR:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* parameters used by path/ovly */
+/* ovly related para: win/addr */
+struct mmp_win {
+ /* position/size of window */
+ u16 xsrc;
+ u16 ysrc;
+ u16 xdst;
+ u16 ydst;
+ u16 xpos;
+ u16 ypos;
+ u16 left_crop;
+ u16 right_crop;
+ u16 up_crop;
+ u16 bottom_crop;
+ int pix_fmt;
+};
+
+struct mmp_addr {
+ /* phys address */
+ u32 phys[6];
+};
+
+/* path related para: mode */
+struct mmp_mode {
+ const char *name;
+ u32 refresh;
+ u32 xres;
+ u32 yres;
+ u32 left_margin;
+ u32 right_margin;
+ u32 upper_margin;
+ u32 lower_margin;
+ u32 hsync_len;
+ u32 vsync_len;
+ u32 hsync_invert;
+ u32 vsync_invert;
+ u32 invert_pixclock;
+ u32 pixclock_freq;
+ int pix_fmt_out;
+};
+
+/* main structures */
+struct mmp_path;
+struct mmp_ovly;
+struct mmp_panel;
+
+/* status types */
+enum {
+ mmp_OFF = 0,
+ mmp_ON,
+};
+
+static inline const char *stat_name(int stat)
+{
+ switch (stat) {
+ case mmp_OFF:
+ return "OFF";
+ case mmp_ON:
+ return "ON";
+ default:
+ return "UNKNOWNSTAT";
+ }
+}
+
+struct mmp_ovly_ops {
+ /* should be provided by driver */
+ void (*set_fetch)(struct mmp_ovly *ovly, int fetch_id);
+ void (*set_onoff)(struct mmp_ovly *ovly, int status);
+ void (*set_win)(struct mmp_ovly *ovly, struct mmp_win *win);
+ int (*set_addr)(struct mmp_ovly *ovly, struct mmp_addr *addr);
+};
+
+/* ovly describes a z-order indexed slot in each path. */
+struct mmp_ovly {
+ int id;
+ const char *name;
+ struct mmp_path *path;
+
+ /* ovly info: private data */
+ int dmafetch_id;
+ struct mmp_addr addr;
+ struct mmp_win win;
+
+ /* state */
+ int open_count;
+ int status;
+ struct mutex access_ok;
+
+ struct mmp_ovly_ops *ops;
+};
+
+/* panel type */
+enum {
+ PANELTYPE_Active = 0,
+ PANELTYPE_Smart,
+ PANELTYPE_TV,
+ PANELTYPE_DSI_CMD,
+ PANELTYPE_DSI_VIDEO,
+};
+
+enum {
+ PANEL_CMDS_SPI,
+ PANEL_CMDS_DSI,
+};
+
+/* commands for panel: commands and sleep time in ms */
+struct mmp_panel_cmds {
+ u16 *cmds;
+ int cmds_num;
+ int sleep;
+};
+
+struct mmp_spi_cfg {
+ u32 clk_cnt;
+ u32 rx_bits;
+ u32 tx_bits;
+ u32 wire_num;
+};
+
+struct mmp_panel_cmd_sets {
+ int type;
+ struct mmp_panel_cmds *on_cmds;
+ int on_cmds_num;
+ struct mmp_panel_cmds *off_cmds;
+ int off_cmds_num;
+ void *config;
+};
+
+struct mmp_panel {
+ /* use node to register to list */
+ struct list_head node;
+ const char *name;
+ /* path name used to connect to proper path configed */
+ const char *plat_path_name;
+ struct device *dev;
+ int panel_type;
+ int (*get_modelist)(struct mmp_panel *panel,
+ struct mmp_mode **modelist);
+ void (*set_mode)(struct mmp_panel *panel,
+ struct mmp_mode *mode);
+ void (*plat_set_onoff)(int status);
+ struct mmp_panel_cmd_sets *cmd_set;
+ /* todo: add query */
+};
+
+struct mmp_path_ops {
+ int (*check_status)(struct mmp_path *path);
+ struct mmp_ovly *(*get_ovly)(struct mmp_path *path,
+ int ovly_id);
+ int (*get_modelist)(struct mmp_path *path,
+ struct mmp_mode **modelist);
+
+ /* follow ops should be provided by driver */
+ void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
+ void (*set_onoff)(struct mmp_path *path, int status);
+ /* todo: add query */
+};
+
+/* path output types */
+enum {
+ PATH_OUT_PARALLEL,
+ PATH_OUT_DSI,
+ PATH_OUT_HDMI,
+};
+
+/* path is main part of mmp-disp */
+struct mmp_path {
+ /* use node to register to list */
+ struct list_head node;
+
+ /* init data */
+ struct device *dev;
+
+ int id;
+ const char *name;
+ int output_type;
+ struct mmp_panel *panel;
+ void *plat_data;
+
+ /* dynamic use */
+ struct mmp_mode mode;
+
+ /* state */
+ int open_count;
+ int status;
+ struct mutex access_ok;
+
+ struct mmp_path_ops ops;
+
+ /* layers */
+ int ovly_num;
+ struct mmp_ovly *ovlys;
+};
+
+extern struct mmp_path *mmp_get_path(const char *name);
+static inline void mmp_path_set_mode(struct mmp_path *path,
+ struct mmp_mode *mode)
+{
+ if (path)
+ path->ops.set_mode(path, mode);
+}
+static inline void mmp_path_set_onoff(struct mmp_path *path, int status)
+{
+ if (path)
+ path->ops.set_onoff(path, status);
+}
+static inline int mmp_path_get_modelist(struct mmp_path *path,
+ struct mmp_mode **modelist)
+{
+ if (path)
+ return path->ops.get_modelist(path, modelist);
+ return 0;
+}
+static inline struct mmp_ovly *mmp_path_get_ovly(
+ struct mmp_path *path, int ovly_id)
+{
+ if (path)
+ return path->ops.get_ovly(path, ovly_id);
+ return NULL;
+}
+static inline void mmp_ovly_set_fetch(struct mmp_ovly *ovly,
+ int fetch_id)
+{
+ if (ovly)
+ ovly->ops->set_fetch(ovly, fetch_id);
+}
+static inline void mmp_ovly_set_onoff(struct mmp_ovly *ovly, int status)
+{
+ if (ovly)
+ ovly->ops->set_onoff(ovly, status);
+}
+static inline void mmp_ovly_set_win(struct mmp_ovly *ovly,
+ struct mmp_win *win)
+{
+ if (ovly)
+ ovly->ops->set_win(ovly, win);
+}
+static inline int mmp_ovly_set_addr(struct mmp_ovly *ovly,
+ struct mmp_addr *addr)
+{
+ if (ovly)
+ return ovly->ops->set_addr(ovly, addr);
+ return 0;
+}
+
+/*
+ * driver data is set from each detailed ctrl driver for path usage
+ * it defined a common interface that plat driver need to implement
+ */
+struct mmp_path_info {
+ /* driver data, set when registed*/
+ const char *name;
+ struct device *dev;
+ int id;
+ int output_type;
+ int ovly_num;
+ void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
+ void (*set_onoff)(struct mmp_path *path, int status);
+ struct mmp_ovly_ops *ovly_ops;
+ void *plat_data;
+};
+
+extern struct mmp_path *mmp_register_path(
+ struct mmp_path_info *info);
+extern void mmp_unregister_path(struct mmp_path *path);
+extern int mmp_register_panel(struct mmp_panel *panel);
+extern void mmp_unregister_panel(struct mmp_panel *panel);
+
+/* defintions for platform data */
+/* interface for buffer driver */
+struct mmp_buffer_driver_mach_info {
+ const char *name;
+ const char *path_name;
+ int ovly_id;
+ int dmafetch_id;
+ int default_pixfmt;
+ u32 irq_mask;
+};
+
+/* interface for controllers driver */
+struct mmp_mach_path_config {
+ const char *name;
+ int ovly_num;
+ int output_type;
+ u32 path_config;
+ u32 link_config;
+};
+
+struct mmp_mach_plat_info {
+ const char *name;
+ const char *clk_name;
+ int path_num;
+ struct mmp_mach_path_config *paths;
+};
+
+/* interface for panel drivers */
+struct mmp_mach_panel_info {
+ const char *name;
+ void (*plat_set_onoff)(int status);
+ const char *plat_path_name;
+};
+#endif /* _MMP_DISP_H_ */
--
1.7.0.4
^ permalink raw reply related
* RE: [PATCH 1/4] video: mmp display subsystem
From: Zhou Zhu @ 2012-08-30 2:26 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1346234684-12532-1-git-send-email-zzhu3@marvell.com>
Hi, Jingoo,
Thank you very much for your review!
I have updated patch according your review results.
Also for the follow patches, I will also remove 'Change-Id' later after your review.
Thanks,
-Zhou
-----Original Message-----
From: Jingoo Han [mailto:jg1.han@samsung.com]
Sent: Thursday, August 30, 2012 9:37 AM
To: Zhou Zhu
Cc: linux-fbdev@vger.kernel.org; FlorianSchandinat@gmx.de; Qing Xu; zzhu84@gmail.com; Lisa Du; 'Jingoo Han'
Subject: Re: [PATCH 1/4] video: mmp display subsystem
On Wednesday, August 29, 2012 7:05 PM Zhou Zhu wrote:
>
> Added mmp display subsystem to support Marvell MMP display controllers.
>
> This subsystem contains 4 parts:
> --fb folder
> --core.c
> --hw folder
> --panel folder
>
> 1. fb folder contains implementation of fb.
> fb get path and ovly from common interface and operates on these structures.
>
> 2. core.c provides common interface for a hardware abstraction.
> Major parts of this interface are:
> a) Path: path is a output device connected to a panel or HDMI TV.
> Main operations of the path is set/get timing/output color.
> fb operates output device through path structure.
> b) Ovly: Ovly is a buffer shown on the path.
> Ovly describes frame buffer and its source/destination size, offset, input
> color, buffer address, z-order, and so on.
> Each fb device maps to one ovly.
>
> 3. hw folder contains implementation of hardware operations defined by core.c.
> It registers paths for fb use.
>
> 4. panel folder contains implementation of panels.
> It's connected to path. Panel drivers would also regiester panels and linked
> to path when probe.
>
> Change-Id: I830e34af9aad3196c2db021b4fb90ceeafbf73d2
Please remove unnecessary 'Change-Id'.
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Lisa Du <cldu@marvell.com>
> ---
> drivers/video/Kconfig | 1 +
> drivers/video/Makefile | 1 +
> drivers/video/mmp/Kconfig | 5 +
> drivers/video/mmp/Makefile | 1 +
> drivers/video/mmp/core.c | 217 +++++++++++++++++++++++++
> include/video/mmp_disp.h | 381 ++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 606 insertions(+), 0 deletions(-)
> create mode 100644 drivers/video/mmp/Kconfig
> create mode 100644 drivers/video/mmp/Makefile
> create mode 100644 drivers/video/mmp/core.c
> create mode 100644 include/video/mmp_disp.h
>
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 0217f74..b71a5c9 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -2447,6 +2447,7 @@ config FB_PUV3_UNIGFX
> source "drivers/video/omap/Kconfig"
> source "drivers/video/omap2/Kconfig"
> source "drivers/video/exynos/Kconfig"
> +source "drivers/video/mmp/Kconfig"
> source "drivers/video/backlight/Kconfig"
>
> if VT
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index ee8dafb..6b0ae31 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -106,6 +106,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
> obj-$(CONFIG_FB_PXA) += pxafb.o
> obj-$(CONFIG_FB_PXA168) += pxa168fb.o
> obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
> +obj-$(CONFIG_MMP_DISP) += mmp/
> obj-$(CONFIG_FB_W100) += w100fb.o
> obj-$(CONFIG_FB_TMIO) += tmiofb.o
> obj-$(CONFIG_FB_AU1100) += au1100fb.o
> diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig
> new file mode 100644
> index 0000000..0554336
> --- /dev/null
> +++ b/drivers/video/mmp/Kconfig
> @@ -0,0 +1,5 @@
> +menuconfig MMP_DISP
> + tristate "Marvell MMP Display Subsystem support"
> + depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
> + help
> + Marvell Display Subsystem support.
> diff --git a/drivers/video/mmp/Makefile b/drivers/video/mmp/Makefile
> new file mode 100644
> index 0000000..820eb10
> --- /dev/null
> +++ b/drivers/video/mmp/Makefile
> @@ -0,0 +1 @@
> +obj-y += core.o
> diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
> new file mode 100644
> index 0000000..b2e7433
> --- /dev/null
> +++ b/drivers/video/mmp/core.c
> @@ -0,0 +1,217 @@
> +/*
> + * linux/drivers/video/mmp/common.c
> + * This driver is a common framework for Marvell Display Controller
> + *
> + * Copyright (C) 2012 Marvell Technology Group Ltd.
> + * Authors: Zhou Zhu <zzhu3@marvell.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * 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/slab.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/export.h>
> +#include <video/mmp_disp.h>
> +
> +static struct mmp_ovly *path_get_ovly(struct mmp_path *path,
> + int ovly_id)
> +{
> + if (path && ovly_id < path->ovly_num)
> + return &path->ovlys[ovly_id];
> + return 0;
> +}
> +
> +static int path_check_status(struct mmp_path *path)
> +{
> + int i;
> + for (i = 0; i < path->ovly_num; i++)
> + if (path->ovlys[i].status)
> + return 1;
> +
> + return 0;
> +}
> +
> +/*
> + * Get modelist write pointer of modelist.
> + * It also returns modelist number
> + * this function fetches modelist from phy/panel:
> + * for HDMI/parallel or dsi to hdmi cases, get from phy
> + * or get from panel
> + */
> +static int path_get_modelist(struct mmp_path *path,
> + struct mmp_mode **modelist)
> +{
> + BUG_ON(!path || !modelist);
> +
> + if (path->panel && path->panel->get_modelist)
> + return path->panel->get_modelist(path->panel, modelist);
> +
> + return 0;
> +}
> +
> +#define list_find(_item, _list, _field, _name) \
> + do {\
> + int found = 0;\
> + list_for_each_entry(_item, &_list, node) {\
> + dev_dbg(_item->dev, "checking %s, target %s",\
> + _item->_field, _name);\
> + if (strcmp(_name, _item->_field) = 0) {\
> + found = 1;\
> + break;\
> + } \
> + } \
> + if (!found)\
> + _item = NULL;\
> + } while (0);
It makes checkpatch warning as below.
WARNING: do {} while (0) macros should not be semicolon terminated
Please remove semicolon as below.
} while (0)
> +
> +/*
> + * panel list is used to pair panel/path when path/panel registered
> + * path list is used for both buffer driver and platdriver
> + * plat driver do path register/unregister
> + * panel driver do panel register/unregister
> + * buffer driver get registered path
> + */
> +static LIST_HEAD(panel_list);
> +static LIST_HEAD(path_list);
> +static DEFINE_MUTEX(disp_lock);
> +
> +int mmp_register_panel(struct mmp_panel *panel)
> +{
> + struct mmp_path *path;
> +
> + mutex_lock(&disp_lock);
> +
> + /* add */
> + list_add_tail(&panel->node, &panel_list);
> +
> + /* try to register to path */
> + list_find(path, path_list, name, panel->plat_path_name);
> + if (path) {
> + dev_info(panel->dev, "register to path %s\n",
> + panel->plat_path_name);
> + path->panel = panel;
> + }
> +
> + mutex_unlock(&disp_lock);
> + return 1;
> +}
> +EXPORT_SYMBOL_GPL(mmp_register_panel);
> +
> +void mmp_unregister_panel(struct mmp_panel *panel)
> +{
> + mutex_lock(&disp_lock);
> + list_del(&panel->node);
> + mutex_unlock(&disp_lock);
> +}
> +EXPORT_SYMBOL_GPL(mmp_unregister_panel);
> +
> +struct mmp_path *mmp_get_path(const char *name)
> +{
> + struct mmp_path *path;
> +
> + mutex_lock(&disp_lock);
> + list_find(path, path_list, name, name);
> + mutex_unlock(&disp_lock);
> +
> + return path;
> +}
> +EXPORT_SYMBOL_GPL(mmp_get_path);
> +
> +struct mmp_path *mmp_register_path(struct mmp_path_info *info)
> +{
> + int i, size;
> + struct mmp_path *path = NULL;
> + struct mmp_panel *panel;
> +
> + size = sizeof(struct mmp_path)
> + + sizeof(struct mmp_ovly) * info->ovly_num;
> + path = kzalloc(size, GFP_KERNEL);
> + if (!path)
> + goto failed;
> +
> + /* path set */
> + path->ovlys = (void *)path + sizeof(struct mmp_path);
> + mutex_init(&path->access_ok);
> + path->dev = info->dev;
> + path->id = info->id;
> + path->name = info->name;
> + path->output_type = info->output_type;
> + path->ovly_num = info->ovly_num;
> + path->plat_data = info->plat_data;
> + path->ops.set_mode = info->set_mode;
> +
> + mutex_lock(&disp_lock);
> + /* get panel */
> + list_find(panel, panel_list, plat_path_name, info->name);
> + if (panel) {
> + dev_info(path->dev, "get panel %s\n", panel->name);
> + path->panel = panel;
> + }
> +
> + dev_info(path->dev, "register %s, ovly_num %d\n",
> + path->name, path->ovly_num);
> +
> + /* default op set: if already set by driver, never cover it */
> + if (!path->ops.check_status)
> + path->ops.check_status = path_check_status;
> + if (!path->ops.get_ovly)
> + path->ops.get_ovly = path_get_ovly;
> + if (!path->ops.get_modelist)
> + path->ops.get_modelist = path_get_modelist;
> +
> + /* step3: init ovlys */
> + for (i = 0; i < path->ovly_num; i++) {
> + path->ovlys[i].path = path;
> + path->ovlys[i].id = i;
> + mutex_init(&path->ovlys[i].access_ok);
> + path->ovlys[i].ops = info->ovly_ops;
> + }
> +
> + /* add to pathlist */
> + list_add_tail(&path->node, &path_list);
> +
> + mutex_unlock(&disp_lock);
> + return path;
> +
> +failed:
> + kfree(path);
> + mutex_unlock(&disp_lock);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(mmp_register_path);
> +
> +void mmp_unregister_path(struct mmp_path *path)
> +{
> + int i;
> +
> + if (!path)
> + return;
> +
> + mutex_lock(&disp_lock);
> + /* del from pathlist */
> + list_del(&path->node);
> +
> + /* deinit ovlys */
> + for (i = 0; i < path->ovly_num; i++)
> + mutex_destroy(&path->ovlys[i].access_ok);
> +
> + mutex_destroy(&path->access_ok);
> +
> + kfree(path);
> + mutex_unlock(&disp_lock);
> +
> + dev_info(path->dev, "de-register %s\n", path->name);
> +}
> +EXPORT_SYMBOL_GPL(mmp_unregister_path);
> diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
> new file mode 100644
> index 0000000..e7318f9
> --- /dev/null
> +++ b/include/video/mmp_disp.h
> @@ -0,0 +1,381 @@
> +/*
> + * linux/include/video/mmp_disp.h
> + * Header file for Marvell MMP Display Controller
> + *
> + * Copyright (C) 2012 Marvell Technology Group Ltd.
> + * Authors: Zhou Zhu <zzhu3@marvell.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * 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/>.
> + *
> + */
> +
> +#ifndef _MMP_DISP_H_
> +#define _MMP_DISP_H_
> +#include <linux/kthread.h>
> +
> +enum {
> + PIXFMT_UYVY = 0,
> + PIXFMT_VYUY,
> + PIXFMT_YUYV,
> + PIXFMT_YUV422P,
> + PIXFMT_YVU422P,
> + PIXFMT_YUV420P,
> + PIXFMT_YVU420P,
> + PIXFMT_RGB565 = 0x100,
> + PIXFMT_BGR565,
> + PIXFMT_RGB1555,
> + PIXFMT_BGR1555,
> + PIXFMT_RGB888PACK,
> + PIXFMT_BGR888PACK,
> + PIXFMT_RGB888UNPACK,
> + PIXFMT_BGR888UNPACK,
> + PIXFMT_RGBA888,
> + PIXFMT_BGRA888,
> + PIXFMT_RGB666, /* for output usage */
> + PIXFMT_PSEUDOCOLOR = 0x200,
> +};
> +
> +static inline int pixfmt_to_stride(int pix_fmt)
> +{
> + switch (pix_fmt) {
> + case PIXFMT_RGB565:
> + case PIXFMT_BGR565:
> + case PIXFMT_RGB1555:
> + case PIXFMT_BGR1555:
> + case PIXFMT_UYVY:
> + case PIXFMT_VYUY:
> + case PIXFMT_YUYV:
> + return 2;
> + case PIXFMT_RGB888UNPACK:
> + case PIXFMT_BGR888UNPACK:
> + case PIXFMT_RGBA888:
> + case PIXFMT_BGRA888:
> + return 4;
> + case PIXFMT_RGB888PACK:
> + case PIXFMT_BGR888PACK:
> + return 3;
> + case PIXFMT_YUV422P:
> + case PIXFMT_YVU422P:
> + case PIXFMT_YUV420P:
> + case PIXFMT_YVU420P:
> + case PIXFMT_PSEUDOCOLOR:
> + return 1;
> + default:
> + return 0;
> + }
> +}
> +
> +/* parameters used by path/ovly */
> +/* ovly related para: win/addr */
> +struct mmp_win {
> + /* position/size of window */
> + u16 xsrc;
> + u16 ysrc;
> + u16 xdst;
> + u16 ydst;
> + u16 xpos;
> + u16 ypos;
> + u16 left_crop;
> + u16 right_crop;
> + u16 up_crop;
> + u16 bottom_crop;
> + int pix_fmt;
> +};
> +
> +struct mmp_addr {
> + /* phys address */
> + u32 phys[6];
> +};
> +
> +/* path related para: mode */
> +struct mmp_mode {
> + const char *name;
> + u32 refresh;
> + u32 xres;
> + u32 yres;
> + u32 left_margin;
> + u32 right_margin;
> + u32 upper_margin;
> + u32 lower_margin;
> + u32 hsync_len;
> + u32 vsync_len;
> + u32 hsync_invert;
> + u32 vsync_invert;
> + u32 invert_pixclock;
> + u32 pixclock_freq;
> + int pix_fmt_out;
> +};
> +
> +/* main structures */
> +struct mmp_path;
> +struct mmp_ovly;
> +struct mmp_panel;
> +
> +
Please remove unnecessary line.
> +/* status types */
> +enum {
> + mmp_OFF = 0,
> + mmp_ON,
> +};
> +
> +static inline const char *stat_name(int stat)
> +{
> + switch (stat) {
> + case mmp_OFF:
> + return "OFF";
> + case mmp_ON:
> + return "ON";
> + default:
> + return "UNKNOWNSTAT";
> + }
> +}
> +
> +struct mmp_ovly_ops {
> + /* should be provided by driver */
> + void (*set_fetch)(struct mmp_ovly *ovly, int fetch_id);
> + void (*set_onoff)(struct mmp_ovly *ovly, int status);
> + void (*set_win)(struct mmp_ovly *ovly, struct mmp_win *win);
> + int (*set_addr)(struct mmp_ovly *ovly, struct mmp_addr *addr);
> +};
> +
> +/* ovly describes a z-order indexed slot in each path. */
> +struct mmp_ovly {
> + int id;
> + const char *name;
> + struct mmp_path *path;
> +
> + /* ovly info: private data */
> + int dmafetch_id;
> + struct mmp_addr addr;
> + struct mmp_win win;
> +
> + /* state */
> + int open_count;
> + int status;
> + struct mutex access_ok;
> +
> + struct mmp_ovly_ops *ops;
> +};
> +
> +/* panel type */
> +enum {
> + PANELTYPE_Active = 0,
> + PANELTYPE_Smart,
> + PANELTYPE_TV,
> + PANELTYPE_DSI_CMD,
> + PANELTYPE_DSI_VIDEO,
> +};
> +
> +enum {
> + PANEL_CMDS_SPI,
> + PANEL_CMDS_DSI,
> +};
> +
> +/* commands for panel: commands and sleep time in ms */
> +struct mmp_panel_cmds {
> + u16 *cmds;
> + int cmds_num;
> + int sleep;
> +};
> +
> +struct mmp_spi_cfg {
> + u32 clk_cnt;
> + u32 rx_bits;
> + u32 tx_bits;
> + u32 wire_num;
> +};
> +
> +struct mmp_panel_cmd_sets {
> + int type;
> + struct mmp_panel_cmds *on_cmds;
> + int on_cmds_num;
> + struct mmp_panel_cmds *off_cmds;
> + int off_cmds_num;
> + void *config;
> +};
> +
> +struct mmp_panel {
> + /* use node to register to list */
> + struct list_head node;
> + const char *name;
> + /* path name used to connect to proper path configed */
> + const char *plat_path_name;
> + struct device *dev;
> + int panel_type;
> + int (*get_modelist)(struct mmp_panel *panel,
> + struct mmp_mode **modelist);
> + void (*set_mode)(struct mmp_panel *panel,
> + struct mmp_mode *mode);
> + void (*plat_set_onoff)(int status);
> + struct mmp_panel_cmd_sets *cmd_set;
> + /* todo: add query */
> +};
> +
> +struct mmp_path_ops {
> + int (*check_status)(struct mmp_path *path);
> + struct mmp_ovly *(*get_ovly)(struct mmp_path *path,
> + int ovly_id);
> + int (*get_modelist)(struct mmp_path *path,
> + struct mmp_mode **modelist);
> +
> + /* follow ops should be provided by driver */
> + void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
> + void (*set_onoff)(struct mmp_path *path, int status);
> + /* todo: add query */
> +};
> +
> +/* path output types */
> +enum {
> + PATH_OUT_PARALLEL,
> + PATH_OUT_DSI,
> + PATH_OUT_HDMI,
> +};
> +
> +/* path is main part of mmp-disp */
> +struct mmp_path {
> + /* use node to register to list */
> + struct list_head node;
> +
> + /* init data */
> + struct device *dev;
> +
> + int id;
> + const char *name;
> + int output_type;
> + struct mmp_panel *panel;
> + void *plat_data;
> +
> + /* dynamic use */
> + struct mmp_mode mode;
> +
> + /* state */
> + int open_count;
> + int status;
> + struct mutex access_ok;
> +
> + struct mmp_path_ops ops;
> +
> + /* layers */
> + int ovly_num;
> + struct mmp_ovly *ovlys;
> +};
> +
> +extern struct mmp_path *mmp_get_path(const char *name);
> +static inline void mmp_path_set_mode(struct mmp_path *path,
> + struct mmp_mode *mode)
> +{
> + if (path)
> + path->ops.set_mode(path, mode);
> +}
> +static inline void mmp_path_set_onoff(struct mmp_path *path, int status)
> +{
> + if (path)
> + path->ops.set_onoff(path, status);
> +}
> +static inline int mmp_path_get_modelist(struct mmp_path *path,
> + struct mmp_mode **modelist)
> +{
> + if (path)
> + return path->ops.get_modelist(path, modelist);
> + return 0;
> +}
> +static inline struct mmp_ovly *mmp_path_get_ovly(
> + struct mmp_path *path, int ovly_id)
> +{
> + if (path)
> + return path->ops.get_ovly(path, ovly_id);
> + return NULL;
> +}
> +static inline void mmp_ovly_set_fetch(struct mmp_ovly *ovly,
> + int fetch_id)
> +{
> + if (ovly)
> + ovly->ops->set_fetch(ovly, fetch_id);
> +}
> +static inline void mmp_ovly_set_onoff(struct mmp_ovly *ovly, int status)
> +{
> + if (ovly)
> + ovly->ops->set_onoff(ovly, status);
> +}
> +static inline void mmp_ovly_set_win(struct mmp_ovly *ovly,
> + struct mmp_win *win)
> +{
> + if (ovly)
> + ovly->ops->set_win(ovly, win);
> +}
> +static inline int mmp_ovly_set_addr(struct mmp_ovly *ovly,
> + struct mmp_addr *addr)
> +{
> + if (ovly)
> + return ovly->ops->set_addr(ovly, addr);
> + return 0;
> +}
> +
> +/*
> + * driver data is set from each detailed ctrl driver for path usage
> + * it defined a common interface that plat driver need to implement
> + */
> +struct mmp_path_info {
> + /* driver data, set when registed*/
> + const char *name;
> + struct device *dev;
> + int id;
> + int output_type;
> + int ovly_num;
> + void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
> + void (*set_onoff)(struct mmp_path *path, int status);
> + struct mmp_ovly_ops *ovly_ops;
> + void *plat_data;
> +};
> +
> +extern struct mmp_path *mmp_register_path(
> + struct mmp_path_info *info);
> +extern void mmp_unregister_path(struct mmp_path *path);
> +extern int mmp_register_panel(struct mmp_panel *panel);
> +extern void mmp_unregister_panel(struct mmp_panel *panel);
> +
> +/* defintions for platform data */
> +/* interface for buffer driver */
> +struct mmp_buffer_driver_mach_info {
> + const char *name;
> + const char *path_name;
> + int ovly_id;
> + int dmafetch_id;
> + int default_pixfmt;
> + u32 irq_mask;
> +};
> +
> +/* interface for controllers driver */
> +struct mmp_mach_path_config {
> + const char *name;
> + int ovly_num;
> + int output_type;
> + u32 path_config;
> + u32 link_config;
> +};
> +
> +struct mmp_mach_plat_info {
> + const char *name;
> + const char *clk_name;
> + int path_num;
> + struct mmp_mach_path_config *paths;
> +};
> +
> +/* interface for panel drivers */
> +struct mmp_mach_panel_info {
> + const char *name;
> + void (*plat_set_onoff)(int status);
> + const char *plat_path_name;
> +};
> +#endif /* _MMP_DISP_H_ */
> --
> 1.7.0.4
>
> --
> 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 00/19] SH Mobile LCDC panel cleanup (including board code)
From: Paul Mundt @ 2012-08-30 6:23 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1345122054-16013-1-git-send-email-laurent.pinchart@ideasonboard.com>
(Resending due to mail server silliness, apologies for any duplicates)
On Mon, Aug 27, 2012 at 05:54:52PM +0900, Simon Horman wrote:
> On Thu, Aug 16, 2012 at 03:00:35PM +0200, Laurent Pinchart wrote:
> > Hi everybody,
> >
> > As part of a general panel API implementation (more on that a bit later), I've
> > cleaned up panel support in the LCDC driver and in the related board code. The
> > result is 19 patches independent of the generic panel API that I would like to
> > get reviewed by the respective board maintainers.
>
> Hi Paul,
>
> I'm happy for you to take all of this, including the mach-shmobile
> portions through your tree if that works for you.
..
> > arch/arm/mach-shmobile/board-ag5evm.c | 198 ++++++++++++++-------------
> > arch/arm/mach-shmobile/board-ap4evb.c | 4 +-
> > arch/arm/mach-shmobile/board-mackerel.c | 6 -
> > arch/sh/boards/mach-ap325rxa/setup.c | 6 -
> > arch/sh/boards/mach-ecovec24/setup.c | 6 -
> > arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 16 +--
> > arch/sh/boards/mach-kfr2r09/setup.c | 7 +-
> > arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 6 +-
> > drivers/video/sh_mipi_dsi.c | 69 ++++------
> > drivers/video/sh_mobile_lcdcfb.c | 54 ++++----
> > drivers/video/sh_mobile_lcdcfb.h | 1 +
> > include/video/sh_mipi_dsi.h | 4 +-
> > include/video/sh_mobile_lcdc.h | 1 -
> > 13 files changed, 172 insertions(+), 206 deletions(-)
> >
Based on the diffstat, the bulk of the change is in the mach-shmobile
directory, so this probably ought to go through your tree to minimize the
potential for merge conflicts. All of the SH stuff is trivival, so
shouldn't be an issue. You're welcome to attach my Acked-by if you like.
^ permalink raw reply
* Re: [PATCH 00/19] SH Mobile LCDC panel cleanup (including board code)
From: Simon Horman @ 2012-08-30 6:27 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1345122054-16013-1-git-send-email-laurent.pinchart@ideasonboard.com>
On Wed, Aug 29, 2012 at 04:58:10PM +0200, Laurent Pinchart wrote:
> Hi Simon,
>
> On Wednesday 29 August 2012 15:07:49 Simon Horman wrote:
> > On Mon, Aug 27, 2012 at 05:35:46PM +0200, Laurent Pinchart wrote:
> > > On Monday 27 August 2012 17:54:52 Simon Horman wrote:
> > > > On Thu, Aug 16, 2012 at 03:00:35PM +0200, Laurent Pinchart wrote:
> > > > > Hi everybody,
> > > > >
> > > > > As part of a general panel API implementation (more on that a bit
> > > > > later), I've cleaned up panel support in the LCDC driver and in the
> > > > > related board code. The result is 19 patches independent of the
> > > > > generic panel API that I would like to get reviewed by the respective
> > > > > board maintainers.
> > > >
> > > > Hi Paul,
> > > >
> > > > I'm happy for you to take all of this, including the mach-shmobile
> > > > portions through your tree if that works for you.
> > >
> > > I usually push the LCDC patches through the fbdev tree. I'm fine with both
> > > options though.
> >
> > I'm happy for you to handle things in your normal way.
> >
> > I guess that means that once the LCDC changes are in the fbdev tree
> > Paul should take the linux-sh changes and I should take the shmobile
> > changes, is that correct?
>
> To avoid bisection breakages all the patches should go through the same tree.
> This will of course increase the chances of merge conflicts. Would you rather
> take them all through linux-sh ?
I'm happy for them to go through the fbdev tree.
Feel free to ad my Ack.
Paul has indicated a similar sentiment in another email in this thread.
^ permalink raw reply
* Re: [PATCH] pwm: Call pwm_enable() before pwm_config()
From: Jingoo Han @ 2012-08-30 7:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50364FA4.7000401@metafoo.de>
On Friday, August 24, 2012 12:44 AM, Lars-Peter Clausen wrote:
>
> On 08/23/2012 04:19 PM, Benoît Thébaudeau wrote:
> > Some PWM drivers enable the clock of the PWM peripheral in pwm_enable(). Hence,
> > for these drivers, a call to pwm_config() does not have any effect before
> > pwm_enable() has been called.
> >
> > This patch fixes the PWM users to make sure that they call pwm_enable() before
> > pwm_config().
> >
> > This fixes the first setting of brightness through sysfs that had no effect with
> > leds-pwm and the i.MX PWM driver.
>
> But isn't this a bug in the PWM peripheral driver? With this change the PWM
> will start with the old settings first. While this is not so much of a problem
> for a backlight (although it might cause a short flickering) it might cause
> problems for other applications, like using the PWM pin as a timing generator.
> In my opinion it's better to fix the PWM peripheral drivers which have this
> problem instead of trying to work around it in every user of the PWM API.
Hi Lars-Peter Clausen,
I think so.
It would be better to fix the PWM peripheral drivers.
Best regards,
Jingoo Han
>
> - Lars
> --
> 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 V5 0/6] OMAPDSS: Cleanup cpu_is checks
From: Tomi Valkeinen @ 2012-08-30 7:34 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev
In-Reply-To: <20120830002039.GP1303@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 4143 bytes --]
On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> * Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> > Hi everyone,
> > this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> > more generic.
> >
> > The 1st patch cleans up cpu_is checks from DISPC code.
> > The 2nd patch removes unused functions from DSS code.
> > The 3rd patch cleans up cpu_is checks from DSS code.
> > The 4th patch removes cpu_is checks from VENC code.
> > The 5th patch disables VENC support on OMAP4.
> > The 6th patch removes cpu_is checks from DPI code and replaces it with a
> > dss feature.
>
> Good to see this, we need this badly to avoid blocking
> single zImage effort on omaps. Can you also please take
What is the issue with single zImage? How do cpu_is_ check affect it?
> a look at the omap dss headers and make sure that
> drivers/video/omap code does not do any #include <mach/*.h>
> or <plat/*.h>?
>
> The driver specific headers should be now moved to live in
> include/linux/platform_data directory instead of the current
> arch/arm/*omap*/include/*.
I had a brief look at drivers/video/omap*. Here's a brief status. I
don't really know much about the old fb driver (drivers/video/omap) so
my comments may not be totally correct. And all fixing I do there is
done in blind, I don't have any omap1 devices.
I've left out the trivial cleanups from the list (i.e. file includes a
header that it doesn't need), there were a bunch of those. I'll make a
patch for these.
$ git grep -E "<plat|<mach" drivers/video/omap*
drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
* Needs to be moved
* lcd_ams_delta uses also omap_write/read
drivers/video/omap/lcd_inn1510.c:#include <plat/fpga.h>
* No idea about this. Who wants to convert the fpga support? =)
drivers/video/omap/lcd_mipid.c:#include <plat/lcd_mipid.h>
* Needs to be moved
drivers/video/omap/lcd_osk.c:#include <plat/mux.h>
* Uses omap_cfg_reg(PWL). I don't know what this is...
* lcd_osk.c uses omap_write/read
drivers/video/omap/lcdc.c:#include <mach/lcdc.h>
* Needs to be moved
drivers/video/omap/lcdc.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c. Any idea about this? Will DMA
engine support OMAP1's LCD DMA?
drivers/video/omap/omapfb_main.c:#include <plat/dma.h>
* Uses DMA API to set DMA priority
drivers/video/omap/sossi.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c
drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
be removed, but is there some other file to include for the time being
than plat/cpu.h?
drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version
drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
drivers/video/omap2/vram.c:#include <plat/vram.h>
drivers/video/omap2/vram.c:#include <plat/dma.h>
drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>
Of these, I'm not sure how to handle.
Grep shows that vram.c is only used by (the newer) omapfb, so it could
be considered a part of that driver. It still needs to be built-in, as
it needs to reserve memory early in the boot process (done with a call
from arch/arm/plat-omap/common.c).
Also board files can use a func call to define the amount of memory to
allocate, but only rx51 seems to do this in the mainline.
Anyway, I believe vram.c is going away when we start to use CMA.
As for vrfb... I'm not really sure where it belongs. It is used by the
newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
controller, so I'm not sure if it's really a normal driver.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH v2 00/23] OMAPDSS: Create output entities
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.
This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices.
Changes since v1:
- Output drivers private data structs hold the output struct rather than
output.c allocating it. This struct is added to a list when
dss_register_output()is called.
- Outputs are not passed from panel driver to output driver anymore. We are
sticking to passing omap_dss_device for now till we get a clearer picture on
how common panel framework turns out. Outputs are still used within the output
driver, rather than passing dssdev everywhere.
Reference tree:
git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs
Archit Taneja (23):
OMAPDSS: outputs: Create a new entity called outputs
OMAPDSS: outputs: Create and register output instances
OMAPDSS: output: Add set/unset device ops for omap_dss_output
OMAPDSS: APPLY: Add manager set/unset output ops for
omap_overlay_manager
OMAPDSS: Remove manager->device references
OMAP_VOUT: Remove manager->device references
OMAPFB: remove manager->device references
OMAPDRM: Remove manager->device references
OMAPDSS: Create links between managers, outputs and devices
OMAPDSS: DPI: Pass omap_dss_output within the driver
OMAPDSS: DSI: Remove dsi_pdev_map global struct
OMAPDSS: DSI: Pass omap_dss_output within the driver
OMAPDSS: SDI: Pass omap_dss_output within the driver
OMAPDSS: RFBI: Pass omap_dss_output within the driver
OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported
functions
OMAPDSS: VENC: Pass omap_dss_output within the driver
OMAPDSS: HDMI: Pass omap_dss_output within the driver
OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions
used by hdmi panel driver
OMAPDSS/OMAPFB: Change dssdev->manager references
OMAPDSS: MANAGER: Update display sysfs store
OMAPDSS: MANAGER: Get device via output
OMAPDSS: APPLY: Remove omap_dss_device references from
dss_ovl_enable/disable
OMAPDSS: Remove old way of setting manager and device links
drivers/media/video/omap/omap_vout.c | 81 +++++++---
drivers/staging/omapdrm/omap_drv.c | 5 +-
drivers/video/omap2/displays/panel-n8x0.c | 55 ++++---
drivers/video/omap2/dss/Makefile | 2 +-
drivers/video/omap2/dss/apply.c | 52 +++---
drivers/video/omap2/dss/dispc.c | 10 +-
drivers/video/omap2/dss/display.c | 11 +-
drivers/video/omap2/dss/dpi.c | 70 +++++---
drivers/video/omap2/dss/dsi.c | 249 ++++++++++++++++++-----------
drivers/video/omap2/dss/dss.h | 23 ++-
drivers/video/omap2/dss/dss_features.c | 52 ++++++
drivers/video/omap2/dss/dss_features.h | 1 +
drivers/video/omap2/dss/hdmi.c | 72 ++++++---
drivers/video/omap2/dss/hdmi_panel.c | 20 +--
drivers/video/omap2/dss/manager.c | 48 ++++--
drivers/video/omap2/dss/output.c | 110 +++++++++++++
drivers/video/omap2/dss/overlay.c | 96 ++++++-----
drivers/video/omap2/dss/rfbi.c | 66 +++++---
drivers/video/omap2/dss/sdi.c | 35 ++--
drivers/video/omap2/dss/venc.c | 47 ++++--
drivers/video/omap2/omapfb/omapfb-ioctl.c | 7 +-
drivers/video/omap2/omapfb/omapfb-main.c | 7 +-
drivers/video/omap2/omapfb/omapfb.h | 5 +-
include/video/omapdss.h | 72 +++++++--
24 files changed, 848 insertions(+), 348 deletions(-)
create mode 100644 drivers/video/omap2/dss/output.c
--
1.7.9.5
^ permalink raw reply
* [PATCH v2 01/23] OMAPDSS: outputs: Create a new entity called outputs
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.
The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.
Adding outputs as a new software entity gives us the following benefits:
- Have exact information on the possible connections between managers and
outputs: A manager can't connect to each and every output, there only limited
hardware links between a manager's video port and some of the outputs.
- Remove hacks related to connecting managers and devices: Currently, default
links between managers and devices are set in a not so clean way. Matching is
done via comparing the device type, and the display types supported by the
manager. This isn't sufficient to establish all the possible links between
managers, outputs and devices in hardware.
- Make panel drivers more generic: The DSS panel drivers currently call
interface/output specific functions to configure the hardware IP. When making
these calls, the driver isn't actually aware of the underlying output. The
output driver extracts information from the panel's omap_dss_device pointer
to figure out which interface it is connected to, and then configures the
corresponding output block. An example of this is when a DSI panel calls
dsi functions, the dsi driver figures out whether the panel is connected
to DSI1 or DSI2. This isn't correct, and having output as entities will
give the panel driver the exact information on which output to configure.
Having outputs also gives the opportunity to make panel drivers generic
across different platforms/SoCs, this is achieved as omap specific output
calls can be replaced by ops of a particular output type.
- Have more complex connections between managers, outputs and devices: OMAPDSS
currently doesn't support use cases like 2 outputs connect to a single
device. This can be achieved by extending properties of outputs to connect to
more managers or devices.
- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
as compared to overlays, managers or devices.
Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
register an output, or look for one. Create an enum which represent each output
instance.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/Makefile | 2 +-
drivers/video/omap2/dss/dss.h | 3 +++
drivers/video/omap2/dss/output.c | 43 ++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 30 ++++++++++++++++++++++++++
4 files changed, 77 insertions(+), 1 deletion(-)
create mode 100644 drivers/video/omap2/dss/output.c
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
- manager.o overlay.o apply.o
+ manager.o overlay.o output.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d6cca82..e77d8d2 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,9 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr);
int dss_ovl_unset_manager(struct omap_overlay *ovl);
+/* output */
+void dss_register_output(struct omap_dss_output *out);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..7d81be5
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.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/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+
+void dss_register_output(struct omap_dss_output *out)
+{
+ list_add_tail(&out->list, &output_list);
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+ struct omap_dss_output *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->id = id)
+ return out;
+ }
+
+ return NULL;
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..2926a04 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
};
+enum omap_dss_output_id {
+ OMAP_DSS_OUTPUT_DPI = 1 << 0,
+ OMAP_DSS_OUTPUT_DBI = 1 << 1,
+ OMAP_DSS_OUTPUT_SDI = 1 << 2,
+ OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
+ OMAP_DSS_OUTPUT_DSI2 = 1 << 4,
+ OMAP_DSS_OUTPUT_VENC = 1 << 5,
+ OMAP_DSS_OUTPUT_HDMI = 1 << 6,
+};
+
/* RFBI */
struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
int pins[OMAP_DSS_MAX_DSI_PINS];
};
+struct omap_dss_output {
+ struct list_head list;
+
+ /* display type supported by the output */
+ enum omap_display_type type;
+
+ /* output instance */
+ enum omap_dss_output_id id;
+
+ /* output's platform device pointer */
+ struct platform_device *pdev;
+
+ /* dynamic fields */
+ struct omap_overlay_manager *manager;
+
+ struct omap_dss_device *device;
+};
+
struct omap_dss_device {
struct device dev;
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
Add output structs to output driver's private data. Register output instances by
having an init function in the probes of the platform device drivers for
different outputs. The *_init_output for each output registers the output and
fill up the output's plaform device, type and id fields.
In the probe of each interface driver, the output entities are initialized
before the *_probe_pdata() functions intentionally. This is done to ensure that
the output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dpi.c | 15 +++++++++++++++
drivers/video/omap2/dss/dsi.c | 18 ++++++++++++++++++
drivers/video/omap2/dss/hdmi.c | 15 +++++++++++++++
drivers/video/omap2/dss/rfbi.c | 17 +++++++++++++++++
drivers/video/omap2/dss/sdi.c | 15 +++++++++++++++
drivers/video/omap2/dss/venc.c | 15 +++++++++++++++
6 files changed, 95 insertions(+)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 25fb895..9a7aee5 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -45,6 +45,8 @@ static struct {
struct omap_video_timings timings;
struct dss_lcd_mgr_config mgr_config;
int data_lines;
+
+ struct omap_dss_output output;
} dpi;
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
}
}
+static void __init dpi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &dpi.output;
+
+ dss_register_output(out);
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_DPI;
+ out->type = OMAP_DISPLAY_TYPE_DPI;
+}
+
static int __init omap_dpi_probe(struct platform_device *pdev)
{
mutex_init(&dpi.lock);
+ dpi_init_output(pdev);
+
dpi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..6a83ab7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -337,6 +337,8 @@ struct dsi_data {
enum omap_dss_dsi_pixel_format pix_fmt;
enum omap_dss_dsi_mode mode;
struct omap_dss_dsi_videomode_timings vm_timings;
+
+ struct omap_dss_output output;
};
struct dsi_packet_sent_handler_data {
@@ -4903,6 +4905,20 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
}
}
+static void __init dsi_init_output(struct platform_device *dsidev,
+ struct dsi_data *dsi)
+{
+ struct omap_dss_output *out = &dsi->output;
+
+ dss_register_output(out);
+
+ out->pdev = dsidev;
+ out->id = dsi->module_id = 0 ?
+ OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out->type = OMAP_DISPLAY_TYPE_DSI;
+}
+
/* DSI1 HW IP initialisation */
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -4997,6 +5013,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
else
dsi->num_lanes_supported = 3;
+ dsi_init_output(dsidev, dsi);
+
dsi_probe_pdata(dsidev);
dsi_runtime_put(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d93954d 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -61,6 +61,8 @@ static struct {
struct hdmi_ip_data ip_data;
struct clk *sys_clk;
+
+ struct omap_dss_output output;
} hdmi;
/*
@@ -890,6 +892,17 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
}
}
+static void __init hdmi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &hdmi.output;
+
+ dss_register_output(out);
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_HDMI;
+ out->type = OMAP_DISPLAY_TYPE_HDMI;
+}
+
/* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{
@@ -933,6 +946,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
+ hdmi_init_output(pdev);
+
hdmi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..3450f51 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -116,6 +116,8 @@ static struct {
int pixel_size;
int data_lines;
struct rfbi_timings intf_timings;
+
+ struct omap_dss_output output;
} rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -967,6 +969,19 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
}
}
+static void __init rfbi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &rfbi.output;
+
+ dss_register_output(out);
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_DBI;
+ out->type = OMAP_DISPLAY_TYPE_DBI;
+
+ return 0;
+}
+
/* RFBI HW IP initialisation */
static int __init omap_rfbihw_probe(struct platform_device *pdev)
{
@@ -1018,6 +1033,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
+ rfbi_init_output(pdev);
+
rfbi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..d8879f3 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -36,6 +36,8 @@ static struct {
struct dss_lcd_mgr_config mgr_config;
struct omap_video_timings timings;
int datapairs;
+
+ struct omap_dss_output output;
} sdi;
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -216,8 +218,21 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
}
}
+static void __init sdi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &sdi.output;
+
+ dss_register_output(out);
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_SDI;
+ out->type = OMAP_DISPLAY_TYPE_SDI;
+}
+
static int __init omap_sdi_probe(struct platform_device *pdev)
{
+ sdi_init_output(pdev);
+
sdi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4a6caf9..942a378 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -304,6 +304,8 @@ static struct {
struct omap_video_timings timings;
enum omap_dss_venc_type type;
bool invert_polarity;
+
+ struct omap_dss_output output;
} venc;
static inline void venc_write_reg(int idx, u32 val)
@@ -773,6 +775,17 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
}
}
+static void __init venc_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &venc.output;
+
+ dss_register_output(out);
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_VENC;
+ out->type = OMAP_DISPLAY_TYPE_VENC;
+}
+
/* VENC HW IP initialisation */
static int __init omap_venchw_probe(struct platform_device *pdev)
{
@@ -820,6 +833,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("venc", venc_dump_regs);
+ venc_init_output(pdev);
+
venc_probe_pdata(pdev);
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.
Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/output.c | 67 ++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 5 +++
2 files changed, 72 insertions(+)
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 7d81be5..abc3aa2 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,9 +24,76 @@
#include "dss.h"
static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (out->device) {
+ DSSERR("output already has device %s connected to it\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->type != dssdev->type) {
+ DSSERR("output type and display type don't match\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device = dssdev;
+ dssdev->output = out;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (!out->device) {
+ DSSERR("output doesn't have a device connected to it\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ DSSERR("device %s is not disabled, cannot unset device\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device->output = NULL;
+ out->device = NULL;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
void dss_register_output(struct omap_dss_output *out)
{
+ out->set_device = &dss_output_set_device;
+ out->unset_device = &dss_output_unset_device;
+
list_add_tail(&out->list, &output_list);
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2926a04..b3fba19 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
struct omap_overlay_manager *manager;
struct omap_dss_device *device;
+
+ int (*set_device) (struct omap_dss_output *out,
+ struct omap_dss_device *dssdev);
+ int (*unset_device) (struct omap_dss_output *out);
};
struct omap_dss_device {
@@ -619,6 +623,7 @@ struct omap_dss_device {
enum omap_display_caps caps;
struct omap_overlay_manager *manager;
+ struct omap_dss_output *output;
enum omap_dss_display_state state;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.
Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/apply.c | 70 ++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 3 ++
drivers/video/omap2/dss/dss_features.c | 52 ++++++++++++++++++++++++
drivers/video/omap2/dss/dss_features.h | 1 +
drivers/video/omap2/dss/manager.c | 4 ++
include/video/omapdss.h | 5 +++
6 files changed, 135 insertions(+)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
return r;
}
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output)
+{
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (mgr->output) {
+ DSSERR("manager %s is already connected to an output\n",
+ mgr->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if ((mgr->supported_outputs & output->id) = 0) {
+ DSSERR("output does not support manager %s\n",
+ mgr->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ output->manager = mgr;
+ mgr->output = output;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+ int r;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
+ mutex_lock(&apply_lock);
+
+ if (!mgr->output) {
+ DSSERR("failed to unset output, output not set\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (mp->enabled) {
+ DSSERR("output can't be unset when manager is enabled\n");
+ r = -EINVAL;
+ goto err1;
+ }
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mgr->output->manager = NULL;
+ mgr->output = NULL;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err1:
+ spin_unlock_irqrestore(&data_lock, flags);
+err:
+ mutex_unlock(&apply_lock);
+
+ return r;
+}
+
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index e77d8d2..de2fb9d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2fe39d6..2872329 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
const int num_mgrs;
const int num_ovls;
const enum omap_display_type *supported_displays;
+ const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
OMAP_DISPLAY_TYPE_DSI,
};
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+ OMAP_DSS_OUTPUT_DPI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -459,6 +500,7 @@ static const struct omap_dss_features omap2_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap2_dss_supported_displays,
+ .supported_outputs = omap2_dss_supported_outputs,
.supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names,
@@ -479,6 +521,7 @@ static const struct omap_dss_features omap3430_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays,
+ .supported_outputs = omap3430_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -498,6 +541,7 @@ static const struct omap_dss_features omap3630_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3630_dss_supported_displays,
+ .supported_outputs = omap3630_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -519,6 +563,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -539,6 +584,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -559,6 +605,7 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -628,6 +675,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
return omap_current_dss_features->supported_displays[channel];
}
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+ return omap_current_dss_features->supported_outputs[channel];
+}
+
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
{
return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 26d43a4..5fe62a8 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -104,6 +104,7 @@ int dss_feat_get_num_ovls(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->set_device = &dss_mgr_set_device;
mgr->unset_device = &dss_mgr_unset_device;
+ mgr->set_output = &dss_mgr_set_output;
+ mgr->unset_output = &dss_mgr_unset_output;
mgr->apply = &omap_dss_mgr_apply;
mgr->set_manager_info = &dss_mgr_set_info;
mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->caps = 0;
mgr->supported_displays dss_feat_get_supported_displays(mgr->id);
+ mgr->supported_outputs + dss_feat_get_supported_outputs(mgr->id);
INIT_LIST_HEAD(&mgr->overlays);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b3fba19..a3b35f9 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
enum omap_overlay_manager_caps caps;
struct list_head overlays;
enum omap_display_type supported_displays;
+ enum omap_dss_output_id supported_outputs;
/* dynamic fields */
struct omap_dss_device *device;
+ struct omap_dss_output *output;
/*
* The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
int (*set_device)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int (*unset_device)(struct omap_overlay_manager *mgr);
+ int (*set_output)(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+ int (*unset_output)(struct omap_overlay_manager *mgr);
int (*set_manager_info)(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 05/23] OMAPDSS: Remove manager->device references
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/apply.c | 6 ++++--
drivers/video/omap2/dss/dispc.c | 10 +++++++---
drivers/video/omap2/dss/manager.c | 19 ++++++++++++++-----
include/video/omapdss.h | 2 ++
4 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err1;
}
- if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ if (ovl->manager = NULL ||
+ ovl->manager->get_device(ovl->manager) = NULL) {
r = -EINVAL;
goto err1;
}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto err;
}
- if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ if (ovl->manager = NULL ||
+ ovl->manager->get_device(ovl->manager) = NULL) {
r = -EINVAL;
goto err;
}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0de9a7e..bfd73f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3549,7 +3549,7 @@ static void dispc_error_worker(struct work_struct *work)
bit = mgr_desc[i].sync_lost_irq;
if (bit & errors) {
- struct omap_dss_device *dssdev = mgr->device;
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
bool enable;
DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3580,9 +3580,13 @@ static void dispc_error_worker(struct work_struct *work)
DSSERR("OCP_ERR\n");
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
+ struct omap_dss_device *dssdev;
+
mgr = omap_dss_get_overlay_manager(i);
- if (mgr->device && mgr->device->driver)
- mgr->device->driver->disable(mgr->device);
+ dssdev = mgr->get_device(mgr);
+
+ if (dssdev && dssdev->driver)
+ dssdev->driver->disable(dssdev);
}
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%s\n",
- mgr->device ? mgr->device->name : "<none>");
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+ dssdev->name : "<none>");
}
static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
if (dssdev)
DSSDBG("display %s found\n", dssdev->name);
- if (mgr->device) {
+ if (mgr->get_device(mgr)) {
r = mgr->unset_device(mgr);
if (r) {
DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
.default_attrs = manager_sysfs_attrs,
};
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+ return mgr->device;
+}
+
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
u32 irq;
int r;
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
if (r)
return r;
- if (mgr->device->type = OMAP_DISPLAY_TYPE_VENC)
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD;
- else if (mgr->device->type = OMAP_DISPLAY_TYPE_HDMI)
+ else if (dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
irq = DISPC_IRQ_EVSYNC_EVEN;
else
irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->get_manager_info = &dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+ mgr->get_device = &dss_mgr_get_device;
mgr->caps = 0;
mgr->supported_displays diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a3b35f9..29c1440 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+ struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
};
/* 22 pins means 1 clk lane and 10 data lanes */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen
Cc: rob, linux-omap, linux-fbdev, Archit Taneja, Vaibhav Hiremath
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/media/video/omap/omap_vout.c | 81 ++++++++++++++++++++++++----------
1 file changed, 57 insertions(+), 24 deletions(-)
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
win = &vout->win;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (!dssdev)
return -EINVAL;
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
outw = win->w.width;
outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
struct omapvideo_info *ovid = &vout->vid_info;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+ if (!dssdev)
return -EINVAL;
ovl->manager->apply(ovl->manager);
}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
- /* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device)
- return;
mgr_id = ovl->manager->id;
- cur_display = ovl->manager->device;
+
+ /* get the display device attached to the overlay */
+ cur_display = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (!cur_display)
+ return;
spin_lock(&vout->vbq_lock);
do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device)
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (dssdev)
ovl->disable(ovl);
}
/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
- if (!ovl->manager || !ovl->manager->device)
+ if (!dssdev)
return -EINVAL;
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
vout->fbuf.fmt.height = timing->y_res;
vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
/* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_fmt_vid_out_exit;
}
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
/* We dont support RGB24-packed mode if vrfb rotation
* is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
struct omapvideo_info *ovid;
struct omap_overlay *ovl;
struct omap_video_timings *timing;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
mutex_lock(&vout->lock);
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_crop_err;
}
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
if (is_rotation_90_or_270(vout)) {
vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_overlay_manager *mgr = ovl->manager;
- if (ovl->manager && ovl->manager->device) {
+ if (mgr && mgr->get_device(mgr)) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
- if (ovl->manager && ovl->manager->device) {
+ if (dssdev) {
ret = ovl->enable(ovl);
if (ret)
goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
- if (ovl->manager && ovl->manager->device)
+ if (dssdev)
ovl->disable(ovl);
}
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
struct video_device *vfd;
struct v4l2_pix_format *pix;
struct v4l2_control *control;
+ struct omap_overlay *ovl = vout->vid_info.overlays[0];
struct omap_dss_device *display - vout->vid_info.overlays[0]->manager->device;
+ ovl->manager->get_device(ovl->manager);
/* set the default pix */
pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
*/
for (i = 1; i < vid_dev->num_overlays; i++) {
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+ NULL;
+ if (dssdev) {
+ def_display = dssdev;
} else {
dev_warn(&pdev->dev, "cannot find display\n");
def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
for (i = 1; i < vid_dev->num_overlays; i++) {
def_display = NULL;
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device)
- def_display = ovl->manager->device;
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+ NULL;
+ if (dssdev)
+ def_display = dssdev;
if (def_display && def_display->driver)
def_display->driver->disable(def_display);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 07/23] OMAPFB: remove manager->device references
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 7 +++++--
drivers/video/omap2/omapfb/omapfb.h | 5 +++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
struct omap_overlay *ovl;
struct omap_dss_device *def_display;
struct omap_dss_device *dssdev;
+ struct omap_dss_device *mgr_device;
DBG("omapfb_probe\n");
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
/* gfx overlay should be the default one. find a display
* connected to that, and use it as default display */
ovl = omap_dss_get_overlay(0);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ mgr_device = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+ if (mgr_device) {
+ def_display = mgr_device;
} else {
dev_warn(&pdev->dev, "cannot find default display\n");
def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
/* XXX: returns the display connected to first attached overlay */
for (i = 0; i < ofbi->num_overlays; i++) {
- if (ofbi->overlays[i]->manager)
- return ofbi->overlays[i]->manager->device;
+ struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+ if (mgr)
+ return mgr->get_device(mgr);
}
return NULL;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 08/23] OMAPDRM: Remove manager->device references
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/staging/omapdrm/omap_drv.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
struct omap_overlay *ovl = omap_dss_get_overlay(i);
struct omap_overlay_manager *mgr = ovl->manager;
- struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+ struct omap_dss_device *dssdev = mgr ?
+ mgr->get_device(mgr) : NULL;
if (dssdev) {
DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
for (j = 0; j < priv->num_encoders; j++) {
struct omap_overlay_manager *mgr omap_encoder_get_manager(priv->encoders[j]);
- if (mgr->device = dssdev) {
+ if (mgr->get_device(mgr) = dssdev) {
drm_mode_connector_attach_encoder(connector,
priv->encoders[j]);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.
The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/overlay.c | 96 +++++++++++++++++++++----------------
1 file changed, 56 insertions(+), 40 deletions(-)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
{
int i;
- struct omap_overlay_manager *lcd_mgr;
- struct omap_overlay_manager *tv_mgr;
- struct omap_overlay_manager *lcd2_mgr = NULL;
- struct omap_overlay_manager *lcd3_mgr = NULL;
struct omap_overlay_manager *mgr = NULL;
+ struct omap_dss_output *out = NULL;
+ enum omap_dss_output_id id;
+
+ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+ break;
+ case OMAP_DISPLAY_TYPE_DBI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+ break;
+ case OMAP_DISPLAY_TYPE_SDI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+ break;
+ case OMAP_DISPLAY_TYPE_VENC:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+ break;
+ case OMAP_DISPLAY_TYPE_HDMI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+ break;
+ case OMAP_DISPLAY_TYPE_DSI:
+ id = dssdev->phy.dsi.module = 0 ? OMAP_DSS_OUTPUT_DSI1 :
+ OMAP_DSS_OUTPUT_DSI2;
+ out = omap_dss_get_output(id);
+ break;
+ default:
+ break;
+ }
- lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
- tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD3))
- lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
- if (dss_has_feature(FEAT_MGR_LCD2))
- lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
- if (dssdev->channel = OMAP_DSS_CHANNEL_LCD3) {
- if (!lcd3_mgr->device || force) {
- if (lcd3_mgr->device)
- lcd3_mgr->unset_device(lcd3_mgr);
- lcd3_mgr->set_device(lcd3_mgr, dssdev);
- mgr = lcd3_mgr;
- }
- } else if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
- if (!lcd2_mgr->device || force) {
- if (lcd2_mgr->device)
- lcd2_mgr->unset_device(lcd2_mgr);
- lcd2_mgr->set_device(lcd2_mgr, dssdev);
- mgr = lcd2_mgr;
- }
- } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
- && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
- if (!lcd_mgr->device || force) {
- if (lcd_mgr->device)
- lcd_mgr->unset_device(lcd_mgr);
- lcd_mgr->set_device(lcd_mgr, dssdev);
- mgr = lcd_mgr;
- }
+ /*
+ * We don't want to touch board files and mention channel for VENC
+ * devices. Force the channel as DIGIT for HDMI and VENC devices
+ */
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC ||
+ dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
+ dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+ if (!mgr || !out) {
+ DSSERR("Incorrect manager or output\n");
+ return;
}
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- if (!tv_mgr->device || force) {
- if (tv_mgr->device)
- tv_mgr->unset_device(tv_mgr);
- tv_mgr->set_device(tv_mgr, dssdev);
- mgr = tv_mgr;
+ if (!mgr->output || force) {
+ struct omap_dss_output *curr_out = mgr->output;
+
+ if (curr_out) {
+ if (curr_out->device)
+ curr_out->unset_device(curr_out);
+ mgr->unset_output(mgr);
}
+ out->set_device(out, dssdev);
+ mgr->set_output(mgr, out);
+ } else {
+ /*
+ * connect a floating output to the device even if the desired
+ * manager is in use
+ */
+ if (!out->manager && !out->device)
+ out->set_device(out, dssdev);
}
if (mgr) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
When a panel driver calls a DPI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DPI driver to configure
the interface.
Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DPI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.
Replace dssdev->manager references with out->manager references as only these
will be valid later.
With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DPI interface functions proceed only if the output is non NULL.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dpi.c | 55 +++++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 21 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 9a7aee5..cb17adb 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -73,7 +73,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
return false;
}
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
@@ -90,7 +90,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
if (r)
return r;
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+ dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
dpi.mgr_config.clock_info = dispc_cinfo;
@@ -101,7 +101,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
return 0;
}
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
@@ -126,7 +126,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
return 0;
}
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
{
struct omap_video_timings *t = &dpi.timings;
int lck_div = 0, pck_div = 0;
@@ -134,11 +134,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
unsigned long pck;
int r = 0;
- if (dpi_use_dsi_pll(dssdev))
- r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+ if (dpi_use_dsi_pll(out->device))
+ r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
&lck_div, &pck_div);
else
- r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+ r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
&lck_div, &pck_div);
if (r)
return r;
@@ -153,12 +153,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
t->pixel_clock = pck;
}
- dss_mgr_set_timings(dssdev->manager, t);
+ dss_mgr_set_timings(out->manager, t);
return 0;
}
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
{
dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
@@ -169,11 +169,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
dpi.mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+ dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
}
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
mutex_lock(&dpi.lock);
@@ -184,10 +185,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_no_reg;
}
- if (dssdev->manager = NULL) {
- DSSERR("failed to enable display: no manager\n");
+ if (out = NULL || out->manager = NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
- goto err_no_mgr;
+ goto err_no_out_mgr;
}
r = omap_dss_start_device(dssdev);
@@ -216,15 +217,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_dsi_pll_init;
}
- r = dpi_set_mode(dssdev);
+ r = dpi_set_mode(out);
if (r)
goto err_set_mode;
- dpi_config_lcd_manager(dssdev);
+ dpi_config_lcd_manager(out);
mdelay(2);
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(out->manager);
if (r)
goto err_mgr_enable;
@@ -247,7 +248,7 @@ err_get_dispc:
err_reg_enable:
omap_dss_stop_device(dssdev);
err_start_dev:
-err_no_mgr:
+err_no_out_mgr:
err_no_reg:
mutex_unlock(&dpi.lock);
return r;
@@ -256,9 +257,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
+
mutex_lock(&dpi.lock);
- dss_mgr_disable(dssdev->manager);
+ dss_mgr_disable(out->manager);
if (dpi_use_dsi_pll(dssdev)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -280,10 +283,16 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
DSSDBG("dpi_set_timings\n");
+ if (out = NULL) {
+ DSSERR("No output connected to %s\n", dssdev->name);
+ return;
+ }
+
mutex_lock(&dpi.lock);
dpi.timings = *timings;
@@ -293,11 +302,11 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
if (r)
return;
- dpi_set_mode(dssdev);
+ dpi_set_mode(out);
dispc_runtime_put();
} else {
- dss_mgr_set_timings(dssdev->manager, timings);
+ dss_mgr_set_timings(out->manager, timings);
}
mutex_unlock(&dpi.lock);
@@ -312,8 +321,12 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
unsigned long fck;
unsigned long pck;
struct dispc_clock_info dispc_cinfo;
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return -ENODEV;
- if (dss_mgr_check_timings(dssdev->manager, timings))
+ if (dss_mgr_check_timings(out->manager, timings))
return -EINVAL;
if (timings->pixel_clock = 0)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
dsi_pdev_map is a struct visible globally in the DSI driver to get the platform
device pointer of the DSI device corresponding to it's module ID. This was
required because there was no clean way to derive the platform device from
the DSI module instance number or from the connected panel.
With the new output entity, it is possible to retrieve the platform device
pointer if the omap_dss_output pointer is available. Modify the functions
dsi_get_dsidev_from_dssdev() dsi_get_dsidev_from_id() so that they use output
instead of dsi_pdev_map to retrieve the dsi platform device pointer.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dsi.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6a83ab7..78212c4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -346,8 +346,6 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
-static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
-
#ifdef DEBUG
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -360,12 +358,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{
- return dsi_pdev_map[dssdev->phy.dsi.module];
+ return dssdev->output->pdev;
}
struct platform_device *dsi_get_dsidev_from_id(int module)
{
- return dsi_pdev_map[module];
+ struct omap_dss_output *out;
+ enum omap_dss_output_id id;
+
+ id = module = 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out = omap_dss_get_output(id);
+
+ return out->pdev;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -4933,7 +4938,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
dsi->module_id = dsidev->id;
dsi->pdev = dsidev;
- dsi_pdev_map[dsi->module_id] = dsidev;
dev_set_drvdata(&dsidev->dev, dsi);
spin_lock_init(&dsi->irq_lock);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 12/23] OMAPDSS: DSI: Pass omap_dss_output within the driver
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1346326845-16583-1-git-send-email-archit@ti.com>
When a panel driver calls a DSI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DSI driver to configure
the interface.
Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DSI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.
Replace dssdev->manager references with out->manager references as only these
will be valid later.
With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DSI interface functions proceed only if the output is non NULL.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dsi.c | 219 ++++++++++++++++++++++++-----------------
1 file changed, 131 insertions(+), 88 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 78212c4..228510f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -356,9 +356,9 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
return dev_get_drvdata(&dsidev->dev);
}
-static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
+static inline struct platform_device *dsi_get_dsidev_from_output(struct omap_dss_output *out)
{
- return dssdev->output->pdev;
+ return out->pdev;
}
struct platform_device *dsi_get_dsidev_from_id(int module)
@@ -391,7 +391,8 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
void dsi_bus_lock(struct omap_dss_device *dssdev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
down(&dsi->bus_lock);
@@ -400,7 +401,8 @@ EXPORT_SYMBOL(dsi_bus_lock);
void dsi_bus_unlock(struct omap_dss_device *dssdev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
up(&dsi->bus_lock);
@@ -1205,15 +1207,15 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
return r;
}
-static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
+static int dsi_set_lp_clk_divisor(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned long dsi_fclk;
unsigned lp_clk_div;
unsigned long lp_clk;
- lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
+ lp_clk_div = out->device->clocks.dsi.lp_clk_div;
if (lp_clk_div = 0 || lp_clk_div > dsi->lpdiv_max)
return -EINVAL;
@@ -2689,7 +2691,8 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
@@ -2817,7 +2820,8 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
DECLARE_COMPLETION_ONSTACK(completion);
int r = 0;
u32 err;
@@ -2986,7 +2990,8 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL,
0, 0);
@@ -3026,7 +3031,8 @@ static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
u8 *data, int len)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
return dsi_vc_write_nosync_common(dsidev, channel, data, len,
DSS_DSI_CONTENT_DCS);
@@ -3036,24 +3042,25 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
u8 *data, int len)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
return dsi_vc_write_nosync_common(dsidev, channel, data, len,
DSS_DSI_CONTENT_GENERIC);
}
EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
-static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
+static int dsi_vc_write_common(struct omap_dss_output *out, int channel,
u8 *data, int len, enum dss_dsi_content_type type)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
int r;
r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type);
if (r)
goto err;
- r = dsi_vc_send_bta_sync(dssdev, channel);
+ r = dsi_vc_send_bta_sync(out->device, channel);
if (r)
goto err;
@@ -3075,7 +3082,9 @@ err:
int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
int len)
{
- return dsi_vc_write_common(dssdev, channel, data, len,
+ struct omap_dss_output *out = dssdev->output;
+
+ return dsi_vc_write_common(out, channel, data, len,
DSS_DSI_CONTENT_DCS);
}
EXPORT_SYMBOL(dsi_vc_dcs_write);
@@ -3083,7 +3092,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write);
int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
int len)
{
- return dsi_vc_write_common(dssdev, channel, data, len,
+ struct omap_dss_output *out = dssdev->output;
+
+ return dsi_vc_write_common(out, channel, data, len,
DSS_DSI_CONTENT_GENERIC);
}
EXPORT_SYMBOL(dsi_vc_generic_write);
@@ -3295,7 +3306,8 @@ err:
int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
u8 *buf, int buflen)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
int r;
r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
@@ -3323,17 +3335,17 @@ err:
}
EXPORT_SYMBOL(dsi_vc_dcs_read);
-static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
+static int dsi_vc_generic_read(struct omap_dss_output *out, int channel,
u8 *reqdata, int reqlen, u8 *buf, int buflen)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
int r;
r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen);
if (r)
return r;
- r = dsi_vc_send_bta_sync(dssdev, channel);
+ r = dsi_vc_send_bta_sync(out->device, channel);
if (r)
return r;
@@ -3353,9 +3365,10 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
int buflen)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
- r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen);
+ r = dsi_vc_generic_read(out, channel, NULL, 0, buf, buflen);
if (r) {
DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel);
return r;
@@ -3368,9 +3381,10 @@ EXPORT_SYMBOL(dsi_vc_generic_read_0);
int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
u8 *buf, int buflen)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
- r = dsi_vc_generic_read(dssdev, channel, ¶m, 1, buf, buflen);
+ r = dsi_vc_generic_read(out, channel, ¶m, 1, buf, buflen);
if (r) {
DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel);
return r;
@@ -3383,13 +3397,14 @@ EXPORT_SYMBOL(dsi_vc_generic_read_1);
int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
u8 param1, u8 param2, u8 *buf, int buflen)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
u8 reqdata[2];
reqdata[0] = param1;
reqdata[1] = param2;
- r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen);
+ r = dsi_vc_generic_read(out, channel, reqdata, 2, buf, buflen);
if (r) {
DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel);
return r;
@@ -3402,7 +3417,8 @@ EXPORT_SYMBOL(dsi_vc_generic_read_2);
int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
u16 len)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
return dsi_vc_send_short(dsidev, channel,
MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
@@ -3738,10 +3754,11 @@ static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs,
return max(lp_inter, 0);
}
-static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
+static void dsi_config_cmd_mode_interleaving(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_device *dssdev = out->device;
int blanking_mode;
int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode;
int hsa, hfp, hbp, width_bytes, bllp, lp_clk_div;
@@ -3856,9 +3873,9 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
dsi_write_reg(dsidev, DSI_VM_TIMING6, r);
}
-static int dsi_proto_config(struct omap_dss_device *dssdev)
+static int dsi_proto_config(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 r;
int buswidth = 0;
@@ -3916,7 +3933,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
dsi_config_vp_sync_events(dsidev);
dsi_config_blanking_modes(dsidev);
- dsi_config_cmd_mode_interleaving(dssdev);
+ dsi_config_cmd_mode_interleaving(out);
}
dsi_vc_initial_config(dsidev, 0);
@@ -4042,7 +4059,8 @@ static void dsi_proto_timings(struct platform_device *dsidev)
int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
const struct omap_dsi_pin_config *pin_cfg)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int num_pins;
const int *pins;
@@ -4109,7 +4127,8 @@ EXPORT_SYMBOL(omapdss_dsi_configure_pins);
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
u8 data_type;
@@ -4150,7 +4169,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
dsi_if_enable(dsidev, true);
}
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(out->manager);
if (r) {
if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
dsi_if_enable(dsidev, false);
@@ -4166,7 +4185,8 @@ EXPORT_SYMBOL(dsi_enable_video_output);
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
@@ -4180,13 +4200,13 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
dsi_if_enable(dsidev, true);
}
- dss_mgr_disable(dssdev->manager);
+ dss_mgr_disable(out->manager);
}
EXPORT_SYMBOL(dsi_disable_video_output);
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
+static void dsi_update_screen_dispc(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned bytespp;
unsigned bytespl;
@@ -4249,9 +4269,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
msecs_to_jiffies(250));
BUG_ON(r = 0);
- dss_mgr_set_timings(dssdev->manager, &dsi->timings);
+ dss_mgr_set_timings(out->manager, &dsi->timings);
- dss_mgr_start_update(dssdev->manager);
+ dss_mgr_start_update(out->manager);
if (dsi->te_enabled) {
/* disable LP_RX_TO, so that we can receive TE. Time to wait
@@ -4325,7 +4345,8 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
void (*callback)(int, void *), void *data)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u16 dw, dh;
@@ -4343,7 +4364,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
dsi->update_bytes = dw * dh *
dsi_get_pixel_size(dsi->pix_fmt) / 8;
#endif
- dsi_update_screen_dispc(dssdev);
+ dsi_update_screen_dispc(out);
return 0;
}
@@ -4351,10 +4372,11 @@ EXPORT_SYMBOL(omap_dsi_update);
/* Display funcs */
-static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
+static int dsi_configure_dispc_clocks(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_device *dssdev = out->device;
struct dispc_clock_info dispc_cinfo;
int r;
unsigned long long fck;
@@ -4375,10 +4397,11 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
return 0;
}
-static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+static int dsi_display_init_dispc(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = out->manager;
int r;
u32 irq = 0;
@@ -4390,7 +4413,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->timings.vfp = 0;
dsi->timings.vbp = 0;
- irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+ irq = dispc_mgr_get_framedone_irq(mgr->id);
r = omap_dispc_register_isr(dsi_framedone_irq_callback,
(void *) dsidev, irq);
@@ -4417,9 +4440,9 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
- dss_mgr_set_timings(dssdev->manager, &dsi->timings);
+ dss_mgr_set_timings(mgr, &dsi->timings);
- r = dsi_configure_dispc_clocks(dssdev);
+ r = dsi_configure_dispc_clocks(out);
if (r)
goto err1;
@@ -4428,7 +4451,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi_get_pixel_size(dsi->pix_fmt);
dsi->mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
+ dss_mgr_set_lcd_config(mgr, &dsi->mgr_config);
return 0;
err1:
@@ -4439,24 +4462,25 @@ err:
return r;
}
-static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
+static void dsi_display_uninit_dispc(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if (dsi->mode = OMAP_DSS_DSI_CMD_MODE) {
u32 irq;
- irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+ irq = dispc_mgr_get_framedone_irq(out->manager->id);
omap_dispc_unregister_isr(dsi_framedone_irq_callback,
(void *) dsidev, irq);
}
}
-static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
+static int dsi_configure_dsi_clocks(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
+ struct omap_dss_device *dssdev = out->device;
struct dsi_clock_info cinfo;
int r;
@@ -4479,23 +4503,25 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
return 0;
}
-static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
+static int dsi_display_init_dsi(struct omap_dss_output *out)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = out->manager;
+ struct omap_dss_device *dssdev = out->device;
int r;
r = dsi_pll_init(dsidev, true, true);
if (r)
goto err0;
- r = dsi_configure_dsi_clocks(dssdev);
+ r = dsi_configure_dsi_clocks(out);
if (r)
goto err1;
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
- dss_select_lcd_clk_source(dssdev->manager->id,
+ dss_select_lcd_clk_source(out->manager->id,
dssdev->clocks.dispc.channel.lcd_clk_src);
DSSDBG("PLL OK\n");
@@ -4507,12 +4533,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
_dsi_print_reset_status(dsidev);
dsi_proto_timings(dsidev);
- dsi_set_lp_clk_divisor(dssdev);
+ dsi_set_lp_clk_divisor(out);
if (1)
_dsi_print_reset_status(dsidev);
- r = dsi_proto_config(dssdev);
+ r = dsi_proto_config(out);
if (r)
goto err3;
@@ -4530,7 +4556,7 @@ err3:
err2:
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
- dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
err1:
dsi_pll_uninit(dsidev, true);
@@ -4538,11 +4564,12 @@ err0:
return r;
}
-static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
+static void dsi_display_uninit_dsi(struct omap_dss_output *out,
bool disconnect_lanes, bool enter_ulps)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = out->manager;
if (enter_ulps && !dsi->ulps_enabled)
dsi_enter_ulps(dsidev);
@@ -4556,29 +4583,33 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
- dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
dsi_cio_uninit(dsidev);
dsi_pll_uninit(dsidev, disconnect_lanes);
}
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev;
+ struct dsi_data *dsi;
int r = 0;
DSSDBG("dsi_display_enable\n");
+ if (out = NULL || out->manager = NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
+ r = -ENODEV;
+ goto err_no_out_mgr;
+ }
+
+ dsidev = dsi_get_dsidev_from_output(out);
+ dsi = dsi_get_dsidrv_data(dsidev);
+
WARN_ON(!dsi_bus_is_locked(dsidev));
mutex_lock(&dsi->lock);
- if (dssdev->manager = NULL) {
- DSSERR("failed to enable display: no manager\n");
- r = -ENODEV;
- goto err_start_dev;
- }
-
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
@@ -4593,11 +4624,11 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
_dsi_initialize_irq(dsidev);
- r = dsi_display_init_dispc(dssdev);
+ r = dsi_display_init_dispc(out);
if (r)
goto err_init_dispc;
- r = dsi_display_init_dsi(dssdev);
+ r = dsi_display_init_dsi(out);
if (r)
goto err_init_dsi;
@@ -4606,7 +4637,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
return 0;
err_init_dsi:
- dsi_display_uninit_dispc(dssdev);
+ dsi_display_uninit_dispc(out);
err_init_dispc:
dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev);
@@ -4614,6 +4645,7 @@ err_get_dsi:
omap_dss_stop_device(dssdev);
err_start_dev:
mutex_unlock(&dsi->lock);
+err_no_out_mgr:
DSSDBG("dsi_display_enable FAILED\n");
return r;
}
@@ -4622,7 +4654,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_enable);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
bool disconnect_lanes, bool enter_ulps)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("dsi_display_disable\n");
@@ -4636,9 +4669,9 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
dsi_sync_vc(dsidev, 2);
dsi_sync_vc(dsidev, 3);
- dsi_display_uninit_dispc(dssdev);
+ dsi_display_uninit_dispc(out);
- dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
+ dsi_display_uninit_dsi(out, disconnect_lanes, enter_ulps);
dsi_runtime_put(dsidev);
dsi_enable_pll_clock(dsidev, 0);
@@ -4651,7 +4684,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_disable);
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
dsi->te_enabled = enable;
@@ -4662,7 +4696,8 @@ EXPORT_SYMBOL(omapdss_dsi_enable_te);
void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
@@ -4675,7 +4710,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_timings);
void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
@@ -4690,7 +4726,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_size);
void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
enum omap_dss_dsi_pixel_format fmt)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
@@ -4704,7 +4741,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
enum omap_dss_dsi_mode mode)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
@@ -4718,7 +4756,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
struct omap_dss_dsi_videomode_timings *timings)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
@@ -4731,7 +4770,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
static int __init dsi_init_display(struct omap_dss_device *dssdev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev + dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("DSI init\n");
@@ -4759,7 +4799,8 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int i;
@@ -4778,7 +4819,8 @@ EXPORT_SYMBOL(omap_dsi_request_vc);
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if (vc_id < 0 || vc_id > 3) {
@@ -4805,7 +4847,8 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id);
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+ struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if ((channel >= 0 && channel <= 3) &&
--
1.7.9.5
^ permalink raw reply related
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