* Re: [RFC v2 0/5] Common Display Framework
From: Laurent Pinchart @ 2012-12-17 15:02 UTC (permalink / raw)
To: Sascha Hauer, Inki Dae
Cc: linux-fbdev, dri-devel, linux-media, Archit Taneja,
Benjamin Gaignard, Jesse Barker, Kyungmin Park, Marcus Lorentzon,
Maxime Ripard, Philipp Zabel, Ragesh Radhakrishnan, Rob Clark,
Sebastien Guiriec, Sumit Semwal, Thomas Petazzoni, Tom Gall,
Tomi Valkeinen, Vikas Sajjan
In-Reply-To: <20121123214158.GO10369@pengutronix.de>
Hi Sascha,
On Friday 23 November 2012 22:41:58 Sascha Hauer wrote:
> On Thu, Nov 22, 2012 at 10:45:31PM +0100, Laurent Pinchart wrote:
> > From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> >
> > The CDF models this using a Russian doll's model. From the display
> > controller point of view only the first external entity (LVDS to DSI
> > converter) is visible. The display controller thus calls the control
> > operations implemented by the LVDS to DSI transmitter driver (left-most
> > green arrow). The driver is aware of the next entity in the chain,
>
> I can't find this in the code. I can see the video operations
> propagating upstream using the source field of struct display_entity,
> but how do the control operations propagate downstream? Am I missing
> something?
There's no downstream propagation yet, as there's no display entity driver
that requires it at the moment. Propagation would be implemented in
transceiver drivers for instance. I'll have to find one with public
documentation (and hopefully an existing mainline driver) on one of the boards
I own.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Laurent Pinchart @ 2012-12-17 15:15 UTC (permalink / raw)
To: Alan Cox, Maxime Ripard
Cc: Tomi Valkeinen, Thierry Reding, Thomas Petazzoni, linux-fbdev,
Benjamin Gaignard, Tom Gall, Kyungmin Park, dri-devel, Rob Clark,
Ragesh Radhakrishnan, Philipp Zabel, Vikas Sajjan, Sumit Semwal,
Sebastien Guiriec, linux-media
In-Reply-To: <20121126144708.3daec09e@pyramind.ukuu.org.uk>
Hi Alan,
On Monday 26 November 2012 14:47:08 Alan Cox wrote:
> On Sat, 24 Nov 2012 09:15:51 +0200 Tomi Valkeinen wrote:
> > On 2012-11-23 21:56, Thierry Reding wrote:
> > > On Thu, Nov 22, 2012 at 10:45:31PM +0100, Laurent Pinchart wrote:
> > > [...]
> > >
> > >> Display entities are accessed by driver using notifiers. Any driver can
> > >> register a display entity notifier with the CDF, which then calls the
> > >> notifier when a matching display entity is registered.
>
> The framebuffer layer has some similar 'anyone can' type notifier
> behaviour and its not a good thing. That kind of "any one can" behaviour
> leads to some really horrible messes unless the connections and the
> locking are well defined IMHO.
I agree with you. I dislike the FBDEV notifier model, and I definitely don't
intend to duplicate it in the common display framework.
In the CDF model, when the display device driver registers a notifier, it
tells the core which device it wants to receive events for. This currently
takes the form of a struct device pointer, and the API will also support
device nodes in a future version (this is still work in progress). The goal is
to implement panel discovery in a way that is compatible with (and very
similar to) hotpluggable display discovery.
Thinking about it now, the API could be cleaner and less subject to abuse if
the notifier was registered for a given video port instead of a given
connected device. I'll add that to my TODO list.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Tomi Valkeinen @ 2012-12-17 15:29 UTC (permalink / raw)
To: Laurent Pinchart
Cc: linux-fbdev, dri-devel, linux-media, Archit Taneja,
Benjamin Gaignard, Bryan Wu, Inki Dae, Jesse Barker,
Kyungmin Park, Marcus Lorentzon, Maxime Ripard, Philipp Zabel,
Ragesh Radhakrishnan, Rob Clark, Sascha Hauer, Sebastien Guiriec,
Sumit Semwal, Thomas Petazzoni, Tom Gall, Vikas Sajjan
In-Reply-To: <1608840.IleINgrx5J@avalon>
[-- Attachment #1: Type: text/plain, Size: 5869 bytes --]
On 2012-12-17 16:36, Laurent Pinchart wrote:
> Hi Tomi,
>
> I finally have time to work on a v3 :-)
>
> On Friday 23 November 2012 16:51:37 Tomi Valkeinen wrote:
>> On 2012-11-22 23:45, Laurent Pinchart wrote:
>>> From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>>>
>>> Hi everybody,
>>>
>>> Here's the second RFC of what was previously known as the Generic Panel
>>> Framework.
>>
>> Nice work! Thanks for working on this.
>>
>> I was doing some testing with the code, seeing how to use it in omapdss.
>> Here are some thoughts:
>>
>> In your model the DSS gets the panel devices connected to it from
>> platform data. After the DSS and the panel drivers are loaded, DSS gets
>> a notification and connects DSS and the panel.
>>
>> I think it's a bit limited way. First of all, it'll make the DT data a
>> bit more complex (although this is not a major problem). With your
>> model, you'll need something like:
>>
>> soc-base.dtsi:
>>
>> dss {
>> dpi0: dpi {
>> };
>> };
>>
>> board.dts:
>>
>> &dpi0 {
>> panel = &dpi-panel;
>> };
>>
>> / {
>> dpi-panel: dpi-panel {
>> ...panel data...;
>> };
>> };
>>
>> Second, it'll prevent hotplug, and even if real hotplug would not be
>> supported, it'll prevent cases where the connected panel must be found
>> dynamically (like reading ID from eeprom).
>
> Hotplug definitely needs to be supported, as the common display framework also
> targets HDMI and DP. The notification mechanism was actually designed to
> support hotplug.
HDMI or DP hotplug may or may not be a different thing than what I talk
about here. We may have two kinds of hotplug: real linux device hotplug,
i.e. a linux device appears or is removed during runtime, or just a
cable hotplug, handled inside a driver, which doesn't have any effect on
the linux devices.
If we do implement HDMI and DP monitors with real linux drivers, then
yes, we could use real hotplug. But we could as well have the monitor
driver always registered, and just have a driver internal cable-hotplug
system.
To be honest, I'm not sure if implementing real hotplug is easily
possible, as we don't have real, probable (probe-able =) busses. So even
if we'd get a hotplug event of a new display device, what kind of device
would the bus master register? It has no way to know that.
> How do you see the proposal preventing hotplug ?
Well, probably it doesn't prevent. But it doesn't feel right to me.
Say, if we have a DPI panel, controlled via foo-bus, which has a probing
mechanism. When the foo-bus master detects a new hardware device, it'll
create linux device for it. The driver for this device will then be
probed. In the probe function it should somehow register itself to the
cdf, or perhaps the previous entity in the chain.
This sounds to me that the link is from the panel to the previous
entity, not the other way around as you describe, and also the previous
entity doesn't know of the panel entities.
>> Third, it kinda creates a cyclical dependency: the DSS needs to know
>> about the panel and calls ops in the panel, and the panel calls ops in
>> the DSS. I'm not sure if this is an actual problem, but I usually find
>> it simpler if calls are done only in one direction.
>
> I don't see any way around that. The panel is not a standalone entity that can
> only receive calls (as it needs to control video streams, per your request
> :-)) or only emit calls (as something needs to control it, userspace doesn't
> control the panel directly).
Right, but as I see it, the destination of the panel's calls, and the
source of the calls to panel are different things. The destination is
the bus layer, dealing with the video signal being transferred. The
source is a bit higher level thing, something that's controlling the
display in general.
>> Here we wouldn't have similar display_entity as you have, but video sources
>> and displays. Video sources are elements in the video pipeline, and a video
>> source is used only by the next downstream element. The last element in the
>> pipeline would not be a video source, but a display, which would be used by
>> the upper layer.
>
> I don't think we should handle pure sources, pure sinks (displays) and mixed
> entities (transceivers) differently. I prefer having abstract entities that
> can have a source and a sink, and expose the corresponding operations. That
> would make pipeline handling much easier, as the code will only need to deal
> with a single type of object. Implementing support for entities with multiple
> sinks and/or sources would also be possible.
Ok. I think having pure sources is simpler model, but it's true that if
we need to iterate and study the pipeline during runtime, it's probably
better to have single entities with multiple sources/sinks.
>> Video source's ops would deal with things related to the video bus in
>> question, like configuring data lanes, sending DSI packets, etc. The
>> display ops would be more high level things, like enable, update, etc.
>> Actually, I guess you could consider the display to represent and deal
>> with the whole pipeline, while video source deals with the bus between
>> two display entities.
>
> What is missing in your proposal is an explanation of how the panel is
> controlled. What does your register_display() function register the display
> with, and what then calls the display operations ?
In my particular case, the omapfb calls the display operations, which is
the higher level "manager" for the whole display. So omapfb does calls
both to the DSS side and to the panel side of the pipeline.
I agree that making calls to both ends is a bit silly, but then again, I
think it also happens in your model, it's just hidden there.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Jani Nikula @ 2012-12-17 16:53 UTC (permalink / raw)
To: Laurent Pinchart, Tomi Valkeinen
Cc: Thomas Petazzoni, linux-fbdev, Philipp Zabel, Tom Gall,
Ragesh Radhakrishnan, dri-devel, Rob Clark, Kyungmin Park,
Benjamin Gaignard, Bryan Wu, Maxime Ripard, Vikas Sajjan,
Sumit Semwal, Sebastien Guiriec, linux-media
In-Reply-To: <1608840.IleINgrx5J@avalon>
Hi Laurent -
On Mon, 17 Dec 2012, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> Hi Tomi,
>
> I finally have time to work on a v3 :-)
>
> On Friday 23 November 2012 16:51:37 Tomi Valkeinen wrote:
>> On 2012-11-22 23:45, Laurent Pinchart wrote:
>> > From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>> >
>> > Hi everybody,
>> >
>> > Here's the second RFC of what was previously known as the Generic Panel
>> > Framework.
>>
>> Nice work! Thanks for working on this.
>>
>> I was doing some testing with the code, seeing how to use it in omapdss.
>> Here are some thoughts:
>>
>> In your model the DSS gets the panel devices connected to it from
>> platform data. After the DSS and the panel drivers are loaded, DSS gets
>> a notification and connects DSS and the panel.
>>
>> I think it's a bit limited way. First of all, it'll make the DT data a
>> bit more complex (although this is not a major problem). With your
>> model, you'll need something like:
>>
>> soc-base.dtsi:
>>
>> dss {
>> dpi0: dpi {
>> };
>> };
>>
>> board.dts:
>>
>> &dpi0 {
>> panel = &dpi-panel;
>> };
>>
>> / {
>> dpi-panel: dpi-panel {
>> ...panel data...;
>> };
>> };
>>
>> Second, it'll prevent hotplug, and even if real hotplug would not be
>> supported, it'll prevent cases where the connected panel must be found
>> dynamically (like reading ID from eeprom).
>
> Hotplug definitely needs to be supported, as the common display framework also
> targets HDMI and DP. The notification mechanism was actually designed to
> support hotplug.
I can see the need for a framework for DSI panels and such (in fact Tomi
and I have talked about it like 2-3 years ago already!) but what is the
story for HDMI and DP? In particular, what's the relationship between
DRM and CDF here? Is there a world domination plan to switch the DRM
drivers to use this framework too? ;) Do you have some rough plans how
DRM and CDF should work together in general?
BR,
Jani.
>
> How do you see the proposal preventing hotplug ?
>
>> Third, it kinda creates a cyclical dependency: the DSS needs to know
>> about the panel and calls ops in the panel, and the panel calls ops in
>> the DSS. I'm not sure if this is an actual problem, but I usually find
>> it simpler if calls are done only in one direction.
>
> I don't see any way around that. The panel is not a standalone entity that can
> only receive calls (as it needs to control video streams, per your request
> :-)) or only emit calls (as something needs to control it, userspace doesn't
> control the panel directly).
>
>> What I suggest is take a simpler approach, something alike to how regulators
>> or gpios are used, even if slightly more complex than those: the entity that
>> has a video output (SoC's DSS, external chips) offers that video output as
>> resource. It doesn't know or care who uses it. The user of the video output
>> (panel, external chips) will find the video output (to which it is connected
>> in the HW) by some means, and will use different operations on that output
>> to operate the device.
>>
>> This would give us something like the following DT data:
>>
>> soc-base.dtsi:
>>
>> dss {
>> dpi0: dpi {
>> };
>> };
>>
>> board.dts:
>>
>> / {
>> dpi-panel: dpi-panel {
>> source = <&dpi0>;
>> ...panel data...;
>> };
>> };
>>
>> The panel driver would do something like this in its probe:
>>
>> int dpi_panel_probe()
>> {
>> // Find the video source, increase ref
>> src = get_video_source_from_of("source");
>>
>> // Reserve the video source for us. others can still get and
>> // observe it, but cannot use it as video data source.
>> // I think this should cascade upstream, so that after this call
>> // each video entity from the panel to the SoC's CRTC is
>> // reserved and locked for this video pipeline.
>> reserve_video_source(src);
>>
>> // set DPI HW configuration, like DPI data lines. The
>> // configuration would come from panel's platform data
>> set_dpi_config(src, config);
>>
>> // register this panel as a display.
>> register_display(this);
>> }
>>
>>
>> The DSS's dpi driver would do something like:
>>
>> int dss_dpi_probe()
>> {
>> // register as a DPI video source
>> register_video_source(this);
>> }
>>
>> A DSI-2-DPI chip would do something like:
>>
>> int dsi2dpi_probe()
>> {
>> // get, reserve and config the DSI bus from SoC
>> src = get_video_source_from_of("source");
>> reserve_video_source(src);
>> set_dsi_config(src, config);
>>
>> // register as a DPI video source
>> register_video_source(this);
>> }
>>
>>
>> Here we wouldn't have similar display_entity as you have, but video sources
>> and displays. Video sources are elements in the video pipeline, and a video
>> source is used only by the next downstream element. The last element in the
>> pipeline would not be a video source, but a display, which would be used by
>> the upper layer.
>
> I don't think we should handle pure sources, pure sinks (displays) and mixed
> entities (transceivers) differently. I prefer having abstract entities that
> can have a source and a sink, and expose the corresponding operations. That
> would make pipeline handling much easier, as the code will only need to deal
> with a single type of object. Implementing support for entities with multiple
> sinks and/or sources would also be possible.
>
>> Video source's ops would deal with things related to the video bus in
>> question, like configuring data lanes, sending DSI packets, etc. The
>> display ops would be more high level things, like enable, update, etc.
>> Actually, I guess you could consider the display to represent and deal
>> with the whole pipeline, while video source deals with the bus between
>> two display entities.
>
> What is missing in your proposal is an explanation of how the panel is
> controlled. What does your register_display() function register the display
> with, and what then calls the display operations ?
>
> --
> Regards,
>
> Laurent Pinchart
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Tony Lindgren @ 2012-12-17 18:29 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Dave Jones, Linus Torvalds, Tomi Valkeinen, linux-omap,
linux-fbdev, linux-kernel, Florian Tobias Schandinat,
Felipe Balbi, Evgeniy Polyakov, Arnd Bergmann
In-Reply-To: <20121217060032.GB13300@core.coreip.homeip.net>
* Dmitry Torokhov <dmitry.torokhov@gmail.com> [121216 22:03]:
> On Sun, Dec 16, 2012 at 12:35:37PM -0800, Tony Lindgren wrote:
> > * Tony Lindgren <tony@atomide.com> [121216 09:49]:
> > > * Dave Jones <davej@redhat.com> [121215 14:27]:
> > > > On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> > > > > On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > > > > > Hi Linus,
> > > > > >
> > > > > > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > > > > > the pull request for fbdev for this merge window.
> > > > >
> > > > > Pulled. However, with this I get the Kconfig question
> > > > >
> > > > > OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
> > > > >
> > > > > which doesn't make a whole lot of sense on x86-64, unless there's
> > > > > something about OMAP2 that I don't know.
> > > > >
> > > > > So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> > > > > least ARM. Because showing it to anybody else seems insane.
> > > > >
> > > > > Same goes for FB_OMAP2 for that matter. I realize that it's likely
> > > > > nice to get compile testing for this on x86-64 too, but if that's the
> > > > > intent, we need to think about it some more. I don't think it's good
> > > > > to ask actual normal users questions like this just for compile
> > > > > coverage.
> > > >
> > > > This OMAP stuff has been creeping into x86 builds for a while.
> > > > Grep from my current build config ..
> > > >
> > > > # CONFIG_OMAP_OCP2SCP is not set
> > > > # CONFIG_KEYBOARD_OMAP4 is not set
> > > > # CONFIG_OMAP2_DSS is not set
> > > > # CONFIG_OMAP_USB2 is not set
> > > >
> > > > There was some other arm-ism that does the same that I' currently forgetting,
> > > > or maybe that got fixed..
> > >
> > > Those are all omap internal devices and should be all marked with
> > > depends on ARCH_OMAP2PLUS.
> > >
> > > It's a different story for external devices that may be used on other
> > > architectures.
> > >
> > > I only came up with one reason to compile internal devices for other
> > > architectures: In some cases the driver subsystem maintainer may want to
> > > be able to compile test subsystem wide changes without having to compile
> > > for each target separately. But for those cases it's trivial to carry a
> > > compile test patch that just drops the depends Kconfig entries.
> >
> > And here's a patch to limit the omap drivers above to omap only.
>
> Do you think we could add a new symbol to debug options, something like
> COMPILE_COVERAGE, and have drivers that can be compiled on platforms
> other than ones having the hardware to do
>
> depend on ARCH_XXX || COMPILE_CONVERAGE
>
> This way people who want to do compile coverage do not have to carry
> patches and allyesconfig will pick this right up.
I like that idea. Looks like Linus already applied the earlier
patch, I'll do a patch for COMPILE_COVERAGE separately.
Regards,
Tony
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Laurent Pinchart @ 2012-12-17 22:19 UTC (permalink / raw)
To: Jani Nikula
Cc: Tomi Valkeinen, Thomas Petazzoni, linux-fbdev, Philipp Zabel,
Tom Gall, Ragesh Radhakrishnan, dri-devel, Rob Clark,
Kyungmin Park, Benjamin Gaignard, Bryan Wu, Maxime Ripard,
Vikas Sajjan, Sumit Semwal, Sebastien Guiriec, linux-media
In-Reply-To: <87pq28hb72.fsf@intel.com>
Hi Jani,
On Monday 17 December 2012 18:53:37 Jani Nikula wrote:
> On Mon, 17 Dec 2012, Laurent Pinchart wrote:
> > On Friday 23 November 2012 16:51:37 Tomi Valkeinen wrote:
> >> On 2012-11-22 23:45, Laurent Pinchart wrote:
> >> > From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> >> >
> >> > Hi everybody,
> >> >
> >> > Here's the second RFC of what was previously known as the Generic Panel
> >> > Framework.
> >>
> >> Nice work! Thanks for working on this.
> >>
> >> I was doing some testing with the code, seeing how to use it in omapdss.
> >> Here are some thoughts:
> >>
> >> In your model the DSS gets the panel devices connected to it from
> >> platform data. After the DSS and the panel drivers are loaded, DSS gets
> >> a notification and connects DSS and the panel.
> >>
> >> I think it's a bit limited way. First of all, it'll make the DT data a
> >> bit more complex (although this is not a major problem). With your
> >> model, you'll need something like:
> >>
> >> soc-base.dtsi:
> >>
> >> dss {
> >> dpi0: dpi {
> >> };
> >> };
> >>
> >> board.dts:
> >>
> >> &dpi0 {
> >> panel = &dpi-panel;
> >> };
> >>
> >> / {
> >> dpi-panel: dpi-panel {
> >> ...panel data...;
> >> };
> >> };
> >>
> >> Second, it'll prevent hotplug, and even if real hotplug would not be
> >> supported, it'll prevent cases where the connected panel must be found
> >> dynamically (like reading ID from eeprom).
> >
> > Hotplug definitely needs to be supported, as the common display framework
> > also targets HDMI and DP. The notification mechanism was actually
> > designed to support hotplug.
>
> I can see the need for a framework for DSI panels and such (in fact Tomi
> and I have talked about it like 2-3 years ago already!) but what is the
> story for HDMI and DP? In particular, what's the relationship between
> DRM and CDF here? Is there a world domination plan to switch the DRM
> drivers to use this framework too? ;) Do you have some rough plans how
> DRM and CDF should work together in general?
There's always a world domination plan, isn't there ? :-)
I certainly want CDF to be used by DRM (or more accurately KMS). That's what
the C stands for, common refers to sharing panel and other display entity
drivers between FBDEV, KMS and V4L2.
I currently have no plan to expose CDF internals to userspace through the KMS
API. We might have to do so later if the hardware complexity grows in such a
way that finer control than what KMS provides needs to be exposed to
userspace, but I don't think we're there yet. The CDF API will thus only be
used internally in the kernel by display controller drivers. The KMS core
might get functions to handle common display entity operations, but the bulk
of the work will be in the display controller drivers to start with. We will
then see what can be abstracted in KMS helper functions.
Regarding HDMI and DP, I imagine HDMI and DP drivers that would use the CDF
API. That's just a thought for now, I haven't tried to implement them, but it
would be nice to handle HDMI screens and DPI/DBI/DSI panels in a generic way.
Do you have thoughts to share on this topic ?
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Laurent Pinchart @ 2012-12-17 23:18 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: linux-fbdev, dri-devel, linux-media, Archit Taneja,
Benjamin Gaignard, Bryan Wu, Inki Dae, Jesse Barker,
Kyungmin Park, Marcus Lorentzon, Maxime Ripard, Philipp Zabel,
Ragesh Radhakrishnan, Rob Clark, Sascha Hauer, Sebastien Guiriec,
Sumit Semwal, Thomas Petazzoni, Tom Gall, Vikas Sajjan
In-Reply-To: <50CF3A4B.8030206@ti.com>
[-- Attachment #1: Type: text/plain, Size: 8668 bytes --]
Hi Tomi,
On Monday 17 December 2012 17:29:15 Tomi Valkeinen wrote:
> On 2012-12-17 16:36, Laurent Pinchart wrote:
> > On Friday 23 November 2012 16:51:37 Tomi Valkeinen wrote:
> >> On 2012-11-22 23:45, Laurent Pinchart wrote:
> >>> From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> >>>
> >>> Hi everybody,
> >>>
> >>> Here's the second RFC of what was previously known as the Generic Panel
> >>> Framework.
> >>
> >> Nice work! Thanks for working on this.
> >>
> >> I was doing some testing with the code, seeing how to use it in omapdss.
> >> Here are some thoughts:
> >>
> >> In your model the DSS gets the panel devices connected to it from
> >> platform data. After the DSS and the panel drivers are loaded, DSS gets
> >> a notification and connects DSS and the panel.
> >>
> >> I think it's a bit limited way. First of all, it'll make the DT data a
> >> bit more complex (although this is not a major problem). With your
> >> model, you'll need something like:
> >>
> >> soc-base.dtsi:
> >>
> >> dss {
> >> dpi0: dpi {
> >> };
> >> };
> >>
> >> board.dts:
> >>
> >> &dpi0 {
> >> panel = &dpi-panel;
> >> };
> >>
> >> / {
> >> dpi-panel: dpi-panel {
> >> ...panel data...;
> >> };
> >> };
> >>
> >> Second, it'll prevent hotplug, and even if real hotplug would not be
> >> supported, it'll prevent cases where the connected panel must be found
> >> dynamically (like reading ID from eeprom).
> >
> > Hotplug definitely needs to be supported, as the common display framework
> > also targets HDMI and DP. The notification mechanism was actually
> > designed to support hotplug.
>
> HDMI or DP hotplug may or may not be a different thing than what I talk
> about here. We may have two kinds of hotplug: real linux device hotplug,
> i.e. a linux device appears or is removed during runtime, or just a cable
> hotplug, handled inside a driver, which doesn't have any effect on the linux
> devices.
>
> If we do implement HDMI and DP monitors with real linux drivers, then yes,
> we could use real hotplug. But we could as well have the monitor driver
> always registered, and just have a driver internal cable-hotplug system.
>
> To be honest, I'm not sure if implementing real hotplug is easily possible,
> as we don't have real, probable (probe-able =) busses. So even if we'd get a
> hotplug event of a new display device, what kind of device would the bus
> master register? It has no way to know that.
I get your point.
My design goal is to handle both HDMI/DP and panels through a single hotplug
interface. I believe it would be simpler for display controller drivers to
handle all display entities with a common API instead of implementing support
for HDMI/DP and panels separately. This would require real HDMI and DP monitor
drivers. I share your concern, I don't know whether this can work in the end,
the only way to find out will be to try it.
> > How do you see the proposal preventing hotplug ?
>
> Well, probably it doesn't prevent. But it doesn't feel right to me.
>
> Say, if we have a DPI panel, controlled via foo-bus, which has a probing
> mechanism. When the foo-bus master detects a new hardware device, it'll
> create linux device for it. The driver for this device will then be probed.
That's correct. That's how Linux handles devices, and I don't think we should
diverge from that model without a very good reason to do so. In my
understanding you agree with me here, could you please confirm that ?
> In the probe function it should somehow register itself to the cdf, or
> perhaps the previous entity in the chain.
The panel driver would register the panel device to CDF in its probe function.
From a panel point of view I think we agree that two sets of operations exist.
- The panel control operations are called by an upper layer component (let's
call it A) to control the panel (retrieve the list of modes, enable the panel,
...). That upper layer component will usually call the panel in response to a
userspace request (that can go through several layers in the kernel before
reaching the panel), but can also call it in response to a hotplug event,
without userspace being involved.
- The panel calls video operations of the entity that provides it with a video
stream (the video source entity, let's call it B) to configure and control the
video bus.
A and B could be implemented in the same driver or in two separate drivers,
but at the end of the day I don't think that matters much. A needs a reference
to the panel, and the panel needs a reference to B, that's all we need to
provide, regardless of whether A and B come from the same kernel module or
not.
> This sounds to me that the link is from the panel to the previous entity,
> not the other way around as you describe, and also the previous entity
> doesn't know of the panel entities.
The data flows from the video source to the panel (I'm 100% confident that we
agree on that :-)), and the video source is controlled by the panel as per
your request. The link is thus from the video source to the panel, but is
controlled by the sink, not the source.
> >> Third, it kinda creates a cyclical dependency: the DSS needs to know
> >> about the panel and calls ops in the panel, and the panel calls ops in
> >> the DSS. I'm not sure if this is an actual problem, but I usually find
> >> it simpler if calls are done only in one direction.
> >
> > I don't see any way around that. The panel is not a standalone entity that
> > can only receive calls (as it needs to control video streams, per your
> > request :-)) or only emit calls (as something needs to control it,
> > userspace doesn't control the panel directly).
>
> Right, but as I see it, the destination of the panel's calls, and the source
> of the calls to panel are different things. The destination is the bus
> layer, dealing with the video signal being transferred. The source is a bit
> higher level thing, something that's controlling the display in general.
That's correct. They can both be implemented in the same driver, but they're
different logical entities. (I actually think they should be implemented in
the same driver, but that's not very relevant here.)
> >> Here we wouldn't have similar display_entity as you have, but video
> >> sources and displays. Video sources are elements in the video pipeline,
> >> and a video source is used only by the next downstream element. The last
> >> element in the pipeline would not be a video source, but a display, which
> >> would be used by the upper layer.
> >
> > I don't think we should handle pure sources, pure sinks (displays) and
> > mixed entities (transceivers) differently. I prefer having abstract
> > entities that can have a source and a sink, and expose the corresponding
> > operations. That would make pipeline handling much easier, as the code
> > will only need to deal with a single type of object. Implementing support
> > for entities with multiple sinks and/or sources would also be possible.
>
> Ok. I think having pure sources is simpler model, but it's true that if
> we need to iterate and study the pipeline during runtime, it's probably
> better to have single entities with multiple sources/sinks.
A pure source is an entity with a source pad only that only exposes source pad
operations, I think the complexity to handle them from the panel point of view
would roughly be the same (there might be an extra argument to a couple of
functions with a pad number, but that's more or less it).
> >> Video source's ops would deal with things related to the video bus in
> >> question, like configuring data lanes, sending DSI packets, etc. The
> >> display ops would be more high level things, like enable, update, etc.
> >> Actually, I guess you could consider the display to represent and deal
> >> with the whole pipeline, while video source deals with the bus between
> >> two display entities.
> >
> > What is missing in your proposal is an explanation of how the panel is
> > controlled. What does your register_display() function register the
> > display with, and what then calls the display operations ?
>
> In my particular case, the omapfb calls the display operations, which is
> the higher level "manager" for the whole display. So omapfb does calls
> both to the DSS side and to the panel side of the pipeline.
>
> I agree that making calls to both ends is a bit silly, but then again, I
> think it also happens in your model, it's just hidden there.
That's probably the biggest difference between our models. Let's discuss it
face to face tomorrow and hopefully come up with an agreement.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Dave Airlie @ 2012-12-18 5:04 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Thomas Petazzoni, linux-fbdev, Philipp Zabel, Tom Gall,
Ragesh Radhakrishnan, dri-devel, Rob Clark, Kyungmin Park,
Tomi Valkeinen, Benjamin Gaignard, Bryan Wu, Maxime Ripard,
Vikas Sajjan, Sumit Semwal, Sebastien Guiriec, linux-media
In-Reply-To: <1353620736-6517-1-git-send-email-laurent.pinchart@ideasonboard.com>
>
> Many developers showed interest in the first RFC, and I've had the opportunity
> to discuss it with most of them. I would like to thank (in no particular
> order) Tomi Valkeinen for all the time he spend helping me to draft v2, Marcus
> Lorentzon for his useful input during Linaro Connect Q4 2012, and Linaro for
> inviting me to Connect and providing a venue to discuss this topic.
>
So this might be a bit off topic but this whole CDF triggered me
looking at stuff I generally avoid:
The biggest problem I'm having currently with the whole ARM graphics
and output world is the proliferation of platform drivers for every
little thing. The whole ordering of operations with respect to things
like suspend/resume or dynamic power management is going to be a real
nightmare if there are dependencies between the drivers. How do you
enforce ordering of s/r operations between all the various components?
The other thing I'd like you guys to do is kill the idea of fbdev and
v4l drivers that are "shared" with the drm codebase, really just
implement fbdev and v4l on top of the drm layer, some people might
think this is some sort of maintainer thing, but really nothing else
makes sense, and having these shared display frameworks just to avoid
having using drm/kms drivers seems totally pointless. Fix the drm
fbdev emulation if an fbdev interface is needed. But creating a fourth
framework because our previous 3 frameworks didn't work out doesn't
seem like a situation I want to get behind too much.
Dave.
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Rob Clark @ 2012-12-18 6:21 UTC (permalink / raw)
To: Dave Airlie
Cc: Laurent Pinchart, Thomas Petazzoni, Linux Fbdev development list,
Philipp Zabel, Tom Gall, Ragesh Radhakrishnan,
dri-devel@lists.freedesktop.org, Kyungmin Park, Tomi Valkeinen,
Benjamin Gaignard, Bryan Wu, Maxime Ripard, Vikas Sajjan,
Sumit Semwal, Sebastien Guiriec, linux-media@vger.kernel.org
In-Reply-To: <CAPM=9txFJzJ0haTyBnr8hEmmqNb+gSAyBno+Zs0Z-qvVMTwz9A@mail.gmail.com>
On Mon, Dec 17, 2012 at 11:04 PM, Dave Airlie <airlied@gmail.com> wrote:
>>
>> Many developers showed interest in the first RFC, and I've had the opportunity
>> to discuss it with most of them. I would like to thank (in no particular
>> order) Tomi Valkeinen for all the time he spend helping me to draft v2, Marcus
>> Lorentzon for his useful input during Linaro Connect Q4 2012, and Linaro for
>> inviting me to Connect and providing a venue to discuss this topic.
>>
>
> So this might be a bit off topic but this whole CDF triggered me
> looking at stuff I generally avoid:
>
> The biggest problem I'm having currently with the whole ARM graphics
> and output world is the proliferation of platform drivers for every
> little thing. The whole ordering of operations with respect to things
> like suspend/resume or dynamic power management is going to be a real
> nightmare if there are dependencies between the drivers. How do you
> enforce ordering of s/r operations between all the various components?
I tend to think that sub-devices are useful just to have a way to
probe hw which may or may not be there, since on ARM we often don't
have any alternative.. but beyond that, suspend/resume, and other
life-cycle aspects, they should really be treated as all one device.
Especially to avoid undefined suspend/resume ordering.
CDF or some sort of mechanism to share panel drivers between drivers
is useful. Keeping it within drm, is probably a good idea, if nothing
else to simplify re-use of helper fxns (like avi-infoframe stuff, for
example) and avoid dealing with merging changes across multiple trees.
Treating them more like shared libraries and less like sub-devices
which can be dynamically loaded/unloaded (ie. they should be not built
as separate modules or suspend/resumed or probed/removed independently
of the master driver) is a really good idea to avoid uncovering nasty
synchronization issues later (remove vs modeset or pageflip) or
surprising userspace in bad ways.
> The other thing I'd like you guys to do is kill the idea of fbdev and
> v4l drivers that are "shared" with the drm codebase, really just
> implement fbdev and v4l on top of the drm layer, some people might
> think this is some sort of maintainer thing, but really nothing else
> makes sense, and having these shared display frameworks just to avoid
> having using drm/kms drivers seems totally pointless. Fix the drm
> fbdev emulation if an fbdev interface is needed. But creating a fourth
> framework because our previous 3 frameworks didn't work out doesn't
> seem like a situation I want to get behind too much.
yeah, let's not have multiple frameworks to do the same thing.. For
fbdev, it is pretty clear that it is a dead end. For v4l2
(subdev+mcf), it is perhaps bit more flexible when it comes to random
arbitrary hw pipelines than kms. But to take advantage of that, your
userspace isn't going to be portable anyways, so you might as well use
driver specific properties/ioctls. But I tend to think that is more
useful for cameras. And from userspace perspective, kms planes are
less painful to use for output than v4l2, so lets stick to drm/kms for
output (and not try to add camera/capture support to kms).. k, thx
BR,
-R
> Dave.
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Vikas Sajjan @ 2012-12-18 6:25 UTC (permalink / raw)
To: dri-devel, linux-fbdev, linux-media
In-Reply-To: <CAD025yQoCiNaKvaCwvUWhk_jV70CPhV35UzV9MR6HtE+1baCxg@mail.gmail.com>
Hi All,
On 17 December 2012 20:55, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Vikas,
>
> Sorry for the late reply. I now have more time to work on CDF, so delays
> should be much shorter.
>
> On Thursday 06 December 2012 10:51:15 Vikas Sajjan wrote:
> > Hi Laurent,
> >
> > I was thinking of porting CDF to samsung EXYNOS 5250 platform, what I found
> > is that, the exynos display controller is MIPI DSI based controller.
> >
> > But if I look at CDF patches, it has only support for MIPI DBI based Display
> > controller.
> >
> > So my question is, do we have any generic framework for MIPI DSI based
> > display controller? basically I wanted to know, how to go about porting CDF
> > for such kind of display controller.
>
> MIPI DSI support is not available yet. The only reason for that is that I
> don't have any MIPI DSI hardware to write and test the code with :-)
>
> The common display framework should definitely support MIPI DSI. I think the
> existing MIPI DBI code could be used as a base, so the implementation
> shouldn't be too high.
>
Yeah, i was also thinking in similar lines, below is my though for
MIPI DSI support in CDF.
o MIPI DSI support as part of CDF framework will expose
> mipi_dsi_register_device(mpi_device) (will be called mach-xxx-dt.c file )
> mipi_dsi_register_driver(mipi_driver, bus ops) (will be called
from platform specific init driver call )
· bus ops will be
o read data
o write data
o write command
> MIPI DSI will be registered as bus_register()
When MIPI DSI probe is called, it (e.g., Exynos or OMAP MIPI DSI) will
initialize the MIPI DSI HW IP.
This probe will also parse the DT file for MIPI DSI based panel, add
the panel device (device_add() ) to kernel and register the display
entity with its control and video ops with CDF.
>
> I can give this a try. Does the existing Exynos 5250 driver support MIPI DSI ?
> Is the device documentation publicly available ? Can you point me to a MIPI
> DSI panel with public documentation (preferably with an existing mainline
> driver if possible) ?
>
yeah, existing Exynos 5250 driver support MIPI DSI ass well as eDP.
i think device documentation is NOT available publicly.
> --
> Regards,
>
> Laurent Pinchart
>
--
Thanks and Regards
Vikas Sajjan
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Daniel Vetter @ 2012-12-18 8:30 UTC (permalink / raw)
To: Rob Clark
Cc: Dave Airlie, Thomas Petazzoni, Linux Fbdev development list,
Benjamin Gaignard, Tom Gall, Kyungmin Park,
dri-devel@lists.freedesktop.org, Ragesh Radhakrishnan,
Tomi Valkeinen, Laurent Pinchart, Philipp Zabel, Bryan Wu,
Maxime Ripard, Vikas Sajjan, Sumit Semwal, Sebastien Guiriec,
linux-media@vger.kernel.org
In-Reply-To: <CAF6AEGsLdLasS4=j1PsX_P8miG8NcTXMUP9VYj+4gdU8Qhm2YQ@mail.gmail.com>
On Tue, Dec 18, 2012 at 7:21 AM, Rob Clark <rob.clark@linaro.org> wrote:
>> The other thing I'd like you guys to do is kill the idea of fbdev and
>> v4l drivers that are "shared" with the drm codebase, really just
>> implement fbdev and v4l on top of the drm layer, some people might
>> think this is some sort of maintainer thing, but really nothing else
>> makes sense, and having these shared display frameworks just to avoid
>> having using drm/kms drivers seems totally pointless. Fix the drm
>> fbdev emulation if an fbdev interface is needed. But creating a fourth
>> framework because our previous 3 frameworks didn't work out doesn't
>> seem like a situation I want to get behind too much.
>
> yeah, let's not have multiple frameworks to do the same thing.. For
> fbdev, it is pretty clear that it is a dead end. For v4l2
> (subdev+mcf), it is perhaps bit more flexible when it comes to random
> arbitrary hw pipelines than kms. But to take advantage of that, your
> userspace isn't going to be portable anyways, so you might as well use
> driver specific properties/ioctls. But I tend to think that is more
> useful for cameras. And from userspace perspective, kms planes are
> less painful to use for output than v4l2, so lets stick to drm/kms for
> output (and not try to add camera/capture support to kms).. k, thx
Yeah, I guess having a v4l device also exported by the same driver
that exports the drm interface might make sense in some cases. But in
many cases I think the video part is just an independent IP block and
shuffling data around with dma-buf is all we really need. So yeah, I
guess sharing display resources between v4l and drm kms driver should
be a last resort option, since coordination (especially if it's
supposed to be somewhat dynamic) will be extremely hairy.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Marcus Lorentzon @ 2012-12-18 10:39 UTC (permalink / raw)
To: Dave Airlie
Cc: Laurent Pinchart, linux-fbdev@vger.kernel.org,
dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org,
Archit Taneja, Benjamin Gaignard, Bryan Wu, Inki Dae,
Jesse Barker, Kyungmin Park, Maxime Ripard, Philipp Zabel,
Ragesh Radhakrishnan, Rob Clark, Sascha Hauer, Sebastien Guiriec,
Sumit Semwal, Thomas Petazzoni, Tom Gall,
Tomi Valkeinen <tomi.valkei>
In-Reply-To: <CAPM=9txFJzJ0haTyBnr8hEmmqNb+gSAyBno+Zs0Z-qvVMTwz9A@mail.gmail.com>
On 12/18/2012 06:04 AM, Dave Airlie wrote:
>> Many developers showed interest in the first RFC, and I've had the opportunity
>> to discuss it with most of them. I would like to thank (in no particular
>> order) Tomi Valkeinen for all the time he spend helping me to draft v2, Marcus
>> Lorentzon for his useful input during Linaro Connect Q4 2012, and Linaro for
>> inviting me to Connect and providing a venue to discuss this topic.
>>
> So this might be a bit off topic but this whole CDF triggered me
> looking at stuff I generally avoid:
I like the effort, right now it seems like x86 and arm display sub
systems are quite different in terms of DRM driver (and HW) design. I
think this is partly due to little information shared about these
different architectures and ideas behind the choices made. I hope some
discussion will light up both sides. And an early discussion will
hopefully give you less pain when CDF drivers starts to get pushed your way.
> The biggest problem I'm having currently with the whole ARM graphics
> and output world is the proliferation of platform drivers for every
> little thing. The whole ordering of operations with respect to things
> like suspend/resume or dynamic power management is going to be a real
> nightmare if there are dependencies between the drivers. How do you
> enforce ordering of s/r operations between all the various components?
Could you give an example? Personally I don't think it is that many. I
might not have counted the plat devs in all arm drivers. But the STE one
have one per HW IP block in the HW (1 DSS + 3 DSI encoder/formatters).
Then of course there are all these panel devices. But I hope that when
CDF is "finished" we will have DSI devices on the DSI bus and DBI
devices on the DBI bus. I think most vendors have used platform devices
for these since they normally can't be probed in a generic way. But as
they are off SoC I feel this is not the best choice. And then many of
the panels are I2C devices (control bus) and that I guess is similar to
"x86" encoders/connectors?
Another part of the difference I feel is that in x86 a DRM device is
most likely a PCI device, and as such has one huge driver for all IPs on
that board. The closest thing we get to that in ARM is probably the DSS
(collection of IPs on SoC, like 3D, 2D, display output, encoders). But
it doesn't fell right to create a single driver for all these. And as
you know often 3D is even from a separate vendor. All these lead up to a
slight increase in the number of devices and drivers. Right way, I feel
so, but you are welcome to show a better way.
> The other thing I'd like you guys to do is kill the idea of fbdev and
> v4l drivers that are "shared" with the drm codebase, really just
> implement fbdev and v4l on top of the drm layer, some people might
> think this is some sort of maintainer thing, but really nothing else
> makes sense, and having these shared display frameworks just to avoid
> having using drm/kms drivers seems totally pointless. Fix the drm
> fbdev emulation if an fbdev interface is needed. But creating a fourth
> framework because our previous 3 frameworks didn't work out doesn't
> seem like a situation I want to get behind too much.
>
I have no intention to use CDF outside KMS connector/encoder and I have
not heard Laurent talk about this either. Personally I see CDF as
"helpers" to create and reuse connector/encoder drivers between SoCs
instead of each SoC do their own panel drivers (which would be about a
hundred, times the number of supported SoCs). We probably need to
discuss the connector/encoder mappings to CDF/panels. But I think we
need to flush out the higher level details like control bus vs. data bus
vs. display entities. While I like the generic way of the display
entities, I also like the pure bus/device/driver model without too many
generalizations.
Do you have any support in x86 world that could be compared to mobile
phone DSI/DBI/DPI panels? That is, different encoder/lcd-driver chips
between the on chip/cpu/SoC CRTC and the external LCD depending on
product (mobile/netbook/...) or is it all HDMI/DP/LVDS etc on x86?
And if you do, how do you model/setup/share all those in DRM driver? Or
it is manageable (< 10) and not up in the hundreds of different
encoders/lcd-drivers?
/BR
/Marcus
^ permalink raw reply
* Re: [RFC v2 0/5] Common Display Framework
From: Sylwester Nawrocki @ 2012-12-18 10:59 UTC (permalink / raw)
To: Rob Clark
Cc: Dave Airlie, Laurent Pinchart, Thomas Petazzoni,
Linux Fbdev development list, Philipp Zabel, Tom Gall,
Ragesh Radhakrishnan, dri-devel@lists.freedesktop.org,
Kyungmin Park, Tomi Valkeinen, Benjamin Gaignard, Bryan Wu,
Maxime Ripard, Vikas Sajjan, Sumit Semwal, Sebastien Guiriec,
linux-media@vger.kernel.org
In-Reply-To: <CAF6AEGsLdLasS4=j1PsX_P8miG8NcTXMUP9VYj+4gdU8Qhm2YQ@mail.gmail.com>
On 12/18/2012 07:21 AM, Rob Clark wrote:
> On Mon, Dec 17, 2012 at 11:04 PM, Dave Airlie<airlied@gmail.com> wrote:
>> So this might be a bit off topic but this whole CDF triggered me
>> looking at stuff I generally avoid:
>>
>> The biggest problem I'm having currently with the whole ARM graphics
>> and output world is the proliferation of platform drivers for every
>> little thing. The whole ordering of operations with respect to things
>> like suspend/resume or dynamic power management is going to be a real
>> nightmare if there are dependencies between the drivers. How do you
>> enforce ordering of s/r operations between all the various components?
There have been already some ideas proposed to resolve this at the PM
subsystem level [1]. And this problem is of course not only specific
to platform drivers. The idea of having monolithic drivers, just because
we can't get the suspend/resume sequences right otherwise, doesn't really
sound appealing. SoC IPs get reused on multiple different SoC series,
no only by single manufacturer. Whole graphics/video subsystems are
composed from smaller blocks in SoCs, with various number of distinct
sub-blocks and same sub-blocks repeated different number of times in
a specific SoC revision.
Expressing an IP as a platform device seems justified to me, often these
platform devices have enough differences to treat them as such. E.g.
belong in different power domain/use different clocks. Except there is
big issue with the power management... However probably more important
is to be able to have driver for a specific IP in a separate module.
And this suspend/resume ordering issue is not only about the platform
devices. E.g. camera subsystem can be composed of an image sensor
sub-device driver, which is most often an I2C client driver, and of
multiple SoC processing blocks. The image sensor can have dependencies
on the SoC sub-blocks. So even if we created monolithic driver for the
SoC part, there are still two pieces to get s/r ordering right - I2C
client and SoC drivers. And please don't propose to merge the sensor
sub-device driver too. There has been a lot of effort in V4L2 to
separate those various functional blocks into sub-devices, so they can
be freely reused, without reimplementing same functionality in each
driver. BTW, there has been a nice talk about these topics at ELCE [2],
particularly slide 22 is interesting.
I believe the solution for these issues really needs to be sought in the
PM subsystem itself.
> I tend to think that sub-devices are useful just to have a way to
> probe hw which may or may not be there, since on ARM we often don't
> have any alternative.. but beyond that, suspend/resume, and other
> life-cycle aspects, they should really be treated as all one device.
> Especially to avoid undefined suspend/resume ordering.
[1] https://lkml.org/lkml/2009/9/9/373
[2]
http://elinux.org/images/9/90/ELCE2012-Modular-Graphics-on-Embedded-ARM.pdf
Thanks,
Sylwester
^ permalink raw reply
* [PATCH] video: ssd1307fb: Fix bit order bug in the byte translation function
From: Maxime Ripard @ 2012-12-18 13:49 UTC (permalink / raw)
To: linux-fbdev
This was leading to a strange behaviour when using the fbcon driver on
top of this one: the letter were in the right order, but each letter was
having a vertical symmetry.
This was because the addressing was right for the byte, but the
addressing of each individual bit was inverted.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: Brian Lilly <brian@crystalfontz.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Thomas Petazzoni <thomas@free-electrons.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
drivers/video/ssd1307fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
index 9e46633..7f5f824 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/ssd1307fb.c
@@ -145,8 +145,8 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
u32 page_length = SSD1307FB_WIDTH * i;
u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8;
u8 byte = *(vmem + index);
- u8 bit = byte & (1 << (7 - (j % 8)));
- bit = bit >> (7 - (j % 8));
+ u8 bit = byte & (1 << (j % 8));
+ bit = bit >> (j % 8);
buf |= bit << k;
}
ssd1307fb_write_data(par->client, buf);
--
1.7.9.5
^ permalink raw reply related
* [PATCHv16 0/7] of: add display helper
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
Hi!
Finally, right in time before the end of the world on friday, v16 of the
display helpers.
Changes since v15:
- move include/linux/{videomode,display_timing}.h to include/video
- move include/linux/of_{videomode,display_timing}.h to include/video
- reimplement flags: add VESA flags and data flags
- let pixelclock in struct videomode be unsigned long
- rename of_display_timings_exists to of_display_timings_exist
- revise logging/error messages: replace __func__ with np->full_name
- rename pixelclk-inverted to pixelclk-active
- revise comments in code
Changes since v14:
- fix "const struct *" warning
(reported by: Leela Krishna Amudala <l.krishna@samsung.com>)
- return -EINVAL when htotal or vtotal are zero
- remove unreachable code in of_get_display_timings
- include headers in .c files and not implicit in .h
- sort includes alphabetically
- fix lower/uppercase in binding documentation
- rebase onto v3.7-rc7
Changes since v13:
- fix "const struct *" warning
(reported by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>)
- prevent division by zero in fb_videomode_from_videomode
Changes since v12:
- rename struct display_timing to via_display_timing in via subsystem
- fix refreshrate calculation
- fix "const struct *" warnings
(reported by: Manjunathappa, Prakash <prakash.pm@ti.com>)
- some CodingStyle fixes
- rewrite parts of commit messages and display-timings.txt
- let display_timing_get_value get all values instead of just typical
Changes since v11:
- make pointers const where applicable
- add reviewed-by Laurent Pinchart
Changes since v10:
- fix function name (drm_)display_mode_from_videomode
- add acked-by, reviewed-by, tested-by
Changes since v9:
- don't leak memory when previous timings were correct
- CodingStyle fixes
- move blank lines around
Changes since v8:
- fix memory leaks
- change API to be more consistent (foo_from_bar(struct bar, struct foo))
- include headers were necessary
- misc minor bugfixes
Changes since v7:
- move of_xxx to drivers/video
- remove non-binding documentation from display-timings.txt
- squash display_timings and videomode in one patch
- misc minor fixes
Changes since v6:
- get rid of some empty lines etc.
- move functions to their subsystems
- split of_ from non-of_ functions
- add at least some kerneldoc to some functions
Changes since v5:
- removed all display stuff and just describe timings
Changes since v4:
- refactored functions
Changes since v3:
- print error messages
- free alloced memory
- general cleanup
Changes since v2:
- use hardware-near property-names
- provide a videomode structure
- allow ranges for all properties (<min,typ,max>)
- functions to get display_mode or fb_videomode
Regards,
Steffen
Steffen Trumtrar (7):
viafb: rename display_timing to via_display_timing
video: add display_timing and videomode
video: add of helper for display timings/videomode
fbmon: add videomode helpers
fbmon: add of_videomode helpers
drm_modes: add videomode helpers
drm_modes: add of_videomode helpers
.../devicetree/bindings/video/display-timing.txt | 109 +++++++++
drivers/gpu/drm/drm_modes.c | 70 ++++++
drivers/video/Kconfig | 21 ++
drivers/video/Makefile | 4 +
drivers/video/display_timing.c | 24 ++
drivers/video/fbmon.c | 94 ++++++++
drivers/video/of_display_timing.c | 239 ++++++++++++++++++++
drivers/video/of_videomode.c | 54 +++++
drivers/video/via/hw.c | 6 +-
drivers/video/via/hw.h | 2 +-
drivers/video/via/lcd.c | 2 +-
drivers/video/via/share.h | 2 +-
drivers/video/via/via_modesetting.c | 8 +-
drivers/video/via/via_modesetting.h | 6 +-
drivers/video/videomode.c | 39 ++++
include/drm/drmP.h | 9 +
include/linux/fb.h | 8 +
include/video/display_timing.h | 124 ++++++++++
include/video/of_display_timing.h | 20 ++
include/video/of_videomode.h | 18 ++
include/video/videomode.h | 48 ++++
21 files changed, 894 insertions(+), 13 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/display-timing.txt
create mode 100644 drivers/video/display_timing.c
create mode 100644 drivers/video/of_display_timing.c
create mode 100644 drivers/video/of_videomode.c
create mode 100644 drivers/video/videomode.c
create mode 100644 include/video/display_timing.h
create mode 100644 include/video/of_display_timing.h
create mode 100644 include/video/of_videomode.h
create mode 100644 include/video/videomode.h
--
1.7.10.4
^ permalink raw reply
* [PATCHv16 1/7] viafb: rename display_timing to via_display_timing
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
The struct display_timing is specific to the via subsystem. The naming leads to
collisions with the new struct display_timing, which is supposed to be a shared
struct between different subsystems.
To clean this up, prepend the existing struct with the subsystem it is specific
to.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/video/via/hw.c | 6 +++---
drivers/video/via/hw.h | 2 +-
drivers/video/via/lcd.c | 2 +-
drivers/video/via/share.h | 2 +-
drivers/video/via/via_modesetting.c | 8 ++++----
drivers/video/via/via_modesetting.h | 6 +++---
6 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 898590d..5563c67 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1467,10 +1467,10 @@ void viafb_set_vclock(u32 clk, int set_iga)
via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
}
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres)
{
- struct display_timing timing;
+ struct via_display_timing timing;
u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
timing.hor_addr = cxres;
@@ -1491,7 +1491,7 @@ struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga)
{
- struct display_timing crt_reg = var_to_timing(var,
+ struct via_display_timing crt_reg = var_to_timing(var,
cxres ? cxres : var->xres, cyres ? cyres : var->yres);
if (iga = IGA1)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 6be243c..c3f2572 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -637,7 +637,7 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres);
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 1650379..022b0df 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -549,7 +549,7 @@ void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
int panel_hres = plvds_setting_info->lcd_panel_hres;
int panel_vres = plvds_setting_info->lcd_panel_vres;
u32 clock;
- struct display_timing timing;
+ struct via_display_timing timing;
struct fb_var_screeninfo panel_var;
const struct fb_videomode *mode_crt_table, *panel_crt_table;
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 3158dfc..65c65c6 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -319,7 +319,7 @@ struct crt_mode_table {
int refresh_rate;
int h_sync_polarity;
int v_sync_polarity;
- struct display_timing crtc;
+ struct via_display_timing crtc;
};
struct io_reg {
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c
index 0e431ae..0b414b0 100644
--- a/drivers/video/via/via_modesetting.c
+++ b/drivers/video/via/via_modesetting.c
@@ -30,9 +30,9 @@
#include "debug.h"
-void via_set_primary_timing(const struct display_timing *timing)
+void via_set_primary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total / 8 - 5;
raw.hor_addr = timing->hor_addr / 8 - 1;
@@ -88,9 +88,9 @@ void via_set_primary_timing(const struct display_timing *timing)
via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
}
-void via_set_secondary_timing(const struct display_timing *timing)
+void via_set_secondary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total - 1;
raw.hor_addr = timing->hor_addr - 1;
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/via/via_modesetting.h
index 06e09fe..f6a6503 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/via/via_modesetting.h
@@ -33,7 +33,7 @@
#define VIA_PITCH_MAX 0x3FF8
-struct display_timing {
+struct via_display_timing {
u16 hor_total;
u16 hor_addr;
u16 hor_blank_start;
@@ -49,8 +49,8 @@ struct display_timing {
};
-void via_set_primary_timing(const struct display_timing *timing);
-void via_set_secondary_timing(const struct display_timing *timing);
+void via_set_primary_timing(const struct via_display_timing *timing);
+void via_set_secondary_timing(const struct via_display_timing *timing);
void via_set_primary_address(u32 addr);
void via_set_secondary_address(u32 addr);
void via_set_primary_pitch(u32 pitch);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 2/7] video: add display_timing and videomode
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Add display_timing structure and the according helper functions. This allows
the description of a display via its supported timing parameters.
Also, add helper functions to convert from display timings to a generic videomode
structure.
The struct display_timing specifies all needed parameters to describe the signal
properties of a display in one mode. This includes
- ranges for signals that may have min-, max- and typical values
- single integers for signals that can be on, off or are ignored
- booleans for signals that are either on or off
As a display may support multiple modes like this, a struct display_timings is
added, that holds all given struct display_timing pointers and declares the
native mode of the display.
Although a display may state that a signal can be in a range, it is driven with
fixed values that indicate a videomode. Therefore graphic drivers don't need all
the information of struct display_timing, but would generate a videomode from
the given set of supported signal timings and work with that.
The video subsystems all define their own structs that describe a mode and work
with that (e.g. fb_videomode or drm_display_mode). To slowly replace all those
various structures and allow code reuse across those subsystems, add struct
videomode as a generic description.
This patch only includes the most basic fields in struct videomode. All missing
fields that are needed to have a really generic video mode description can be
added at a later stage.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/Kconfig | 6 ++
drivers/video/Makefile | 2 +
drivers/video/display_timing.c | 24 ++++++++
drivers/video/videomode.c | 39 +++++++++++++
include/video/display_timing.h | 124 ++++++++++++++++++++++++++++++++++++++++
include/video/videomode.h | 48 ++++++++++++++++
6 files changed, 243 insertions(+)
create mode 100644 drivers/video/display_timing.c
create mode 100644 drivers/video/videomode.c
create mode 100644 include/video/display_timing.h
create mode 100644 include/video/videomode.h
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d799..2a23b18 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -33,6 +33,12 @@ config VIDEO_OUTPUT_CONTROL
This framework adds support for low-level control of the video
output switch.
+config DISPLAY_TIMING
+ bool
+
+config VIDEOMODE
+ bool
+
menuconfig FB
tristate "Support for frame buffer devices"
---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..fc30439 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -167,3 +167,5 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_VIDEOMODE) += videomode.o
diff --git a/drivers/video/display_timing.c b/drivers/video/display_timing.c
new file mode 100644
index 0000000..5e1822c
--- /dev/null
+++ b/drivers/video/display_timing.c
@@ -0,0 +1,24 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <video/display_timing.h>
+
+void display_timings_release(struct display_timings *disp)
+{
+ if (disp->timings) {
+ unsigned int i;
+
+ for (i = 0; i < disp->num_timings; i++)
+ kfree(disp->timings[i]);
+ kfree(disp->timings);
+ }
+ kfree(disp);
+}
+EXPORT_SYMBOL_GPL(display_timings_release);
diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c
new file mode 100644
index 0000000..21c47a2
--- /dev/null
+++ b/drivers/video/videomode.c
@@ -0,0 +1,39 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <video/display_timing.h>
+#include <video/videomode.h>
+
+int videomode_from_timing(const struct display_timings *disp,
+ struct videomode *vm, unsigned int index)
+{
+ struct display_timing *dt;
+
+ dt = display_timings_get(disp, index);
+ if (!dt)
+ return -EINVAL;
+
+ vm->pixelclock = display_timing_get_value(&dt->pixelclock, TE_TYP);
+ vm->hactive = display_timing_get_value(&dt->hactive, TE_TYP);
+ vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, TE_TYP);
+ vm->hback_porch = display_timing_get_value(&dt->hback_porch, TE_TYP);
+ vm->hsync_len = display_timing_get_value(&dt->hsync_len, TE_TYP);
+
+ vm->vactive = display_timing_get_value(&dt->vactive, TE_TYP);
+ vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, TE_TYP);
+ vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP);
+ vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP);
+
+ vm->dmt_flags = dt->dmt_flags;
+ vm->data_flags = dt->data_flags;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_from_timing);
diff --git a/include/video/display_timing.h b/include/video/display_timing.h
new file mode 100644
index 0000000..71e9a38
--- /dev/null
+++ b/include/video/display_timing.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * description of display timings
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_DISPLAY_TIMING_H
+#define __LINUX_DISPLAY_TIMING_H
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+/* VESA display monitor timing parameters */
+#define VESA_DMT_HSYNC_LOW BIT(0)
+#define VESA_DMT_HSYNC_HIGH BIT(1)
+#define VESA_DMT_VSYNC_LOW BIT(2)
+#define VESA_DMT_VSYNC_HIGH BIT(3)
+
+/* display specific flags */
+#define DISPLAY_FLAGS_DE_LOW BIT(0) /* data enable flag */
+#define DISPLAY_FLAGS_DE_HIGH BIT(1)
+#define DISPLAY_FLAGS_PIXDATA_POSEDGE BIT(2) /* drive data on pos. edge */
+#define DISPLAY_FLAGS_PIXDATA_NEGEDGE BIT(3) /* drive data on neg. edge */
+#define DISPLAY_FLAGS_INTERLACED BIT(4)
+#define DISPLAY_FLAGS_DOUBLESCAN BIT(5)
+
+/*
+ * A single signal can be specified via a range of minimal and maximal values
+ * with a typical value, that lies somewhere inbetween.
+ */
+struct timing_entry {
+ u32 min;
+ u32 typ;
+ u32 max;
+};
+
+enum timing_entry_index {
+ TE_MIN = 0,
+ TE_TYP = 1,
+ TE_MAX = 2,
+};
+
+/*
+ * Single "mode" entry. This describes one set of signal timings a display can
+ * have in one setting. This struct can later be converted to struct videomode
+ * (see include/video/videomode.h). As each timing_entry can be defined as a
+ * range, one struct display_timing may become multiple struct videomodes.
+ *
+ * Example: hsync active high, vsync active low
+ *
+ * Active Video
+ * Video ______________________XXXXXXXXXXXXXXXXXXXXXX_____________________
+ * |<- sync ->|<- back ->|<----- active ----->|<- front ->|<- sync..
+ * | | porch | | porch |
+ *
+ * HSync _|¯¯¯¯¯¯¯¯¯¯|___________________________________________|¯¯¯¯¯¯¯¯¯
+ *
+ * VSync ¯|__________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_________
+ */
+struct display_timing {
+ struct timing_entry pixelclock;
+
+ struct timing_entry hactive; /* hor. active video */
+ struct timing_entry hfront_porch; /* hor. front porch */
+ struct timing_entry hback_porch; /* hor. back porch */
+ struct timing_entry hsync_len; /* hor. sync len */
+
+ struct timing_entry vactive; /* ver. active video */
+ struct timing_entry vfront_porch; /* ver. front porch */
+ struct timing_entry vback_porch; /* ver. back porch */
+ struct timing_entry vsync_len; /* ver. sync len */
+
+ unsigned int dmt_flags; /* VESA DMT flags */
+ unsigned int data_flags; /* video data flags */
+};
+
+/*
+ * This describes all timing settings a display provides.
+ * The native_mode is the default setting for this display.
+ * Drivers that can handle multiple videomodes should work with this struct and
+ * convert each entry to the desired end result.
+ */
+struct display_timings {
+ unsigned int num_timings;
+ unsigned int native_mode;
+
+ struct display_timing **timings;
+};
+
+/* get value specified by index from struct timing_entry */
+static inline u32 display_timing_get_value(const struct timing_entry *te,
+ enum timing_entry_index index)
+{
+ switch (index) {
+ case TE_MIN:
+ return te->min;
+ break;
+ case TE_TYP:
+ return te->typ;
+ break;
+ case TE_MAX:
+ return te->max;
+ break;
+ default:
+ return te->typ;
+ }
+}
+
+/* get one entry from struct display_timings */
+static inline struct display_timing *display_timings_get(const struct
+ display_timings *disp,
+ unsigned int index)
+{
+ if (disp->num_timings > index)
+ return disp->timings[index];
+ else
+ return NULL;
+}
+
+void display_timings_release(struct display_timings *disp);
+
+#endif
diff --git a/include/video/videomode.h b/include/video/videomode.h
new file mode 100644
index 0000000..a421562
--- /dev/null
+++ b/include/video/videomode.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * generic videomode description
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_VIDEOMODE_H
+#define __LINUX_VIDEOMODE_H
+
+#include <linux/types.h>
+#include <video/display_timing.h>
+
+/*
+ * Subsystem independent description of a videomode.
+ * Can be generated from struct display_timing.
+ */
+struct videomode {
+ unsigned long pixelclock; /* pixelclock in Hz */
+
+ u32 hactive;
+ u32 hfront_porch;
+ u32 hback_porch;
+ u32 hsync_len;
+
+ u32 vactive;
+ u32 vfront_porch;
+ u32 vback_porch;
+ u32 vsync_len;
+
+ unsigned int dmt_flags; /* VESA DMT flags */
+ unsigned int data_flags; /* video data flags */
+};
+
+/**
+ * videomode_from_timing - convert display timing to videomode
+ * @disp: structure with all possible timing entries
+ * @vm: return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function converts a struct display_timing to a struct videomode.
+ */
+int videomode_from_timing(const struct display_timings *disp,
+ struct videomode *vm, unsigned int index);
+
+#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 3/7] video: add of helper for display timings/videomode
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Philipp Zabel, Rob Herring, linux-fbdev,
dri-devel, Laurent Pinchart, Thierry Reding,
Guennady Liakhovetski, linux-media, Tomi Valkeinen,
Stephen Warren, kernel, Florian Tobias Schandinat, David Airlie,
Rob Clark, Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
This adds support for reading display timings from DT into a struct
display_timings. The of_display_timing implementation supports multiple
subnodes. All children are read into an array, that can be queried.
If no native mode is specified, the first subnode will be used.
For cases where the graphics driver knows there can be only one
mode description or where the driver only supports one mode, a helper
function of_get_videomode is added, that gets a struct videomode from DT.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
.../devicetree/bindings/video/display-timing.txt | 109 +++++++++
drivers/video/Kconfig | 15 ++
drivers/video/Makefile | 2 +
drivers/video/of_display_timing.c | 239 ++++++++++++++++++++
drivers/video/of_videomode.c | 54 +++++
include/video/of_display_timing.h | 20 ++
include/video/of_videomode.h | 18 ++
7 files changed, 457 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/display-timing.txt
create mode 100644 drivers/video/of_display_timing.c
create mode 100644 drivers/video/of_videomode.c
create mode 100644 include/video/of_display_timing.h
create mode 100644 include/video/of_videomode.h
diff --git a/Documentation/devicetree/bindings/video/display-timing.txt b/Documentation/devicetree/bindings/video/display-timing.txt
new file mode 100644
index 0000000..1500385
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/display-timing.txt
@@ -0,0 +1,109 @@
+display-timing bindings
+===========+
+display-timings node
+--------------------
+
+required properties:
+ - none
+
+optional properties:
+ - native-mode: The native mode for the display, in case multiple modes are
+ provided. When omitted, assume the first node is the native.
+
+timing subnode
+--------------
+
+required properties:
+ - hactive, vactive: display resolution
+ - hfront-porch, hback-porch, hsync-len: horizontal display timing parameters
+ in pixels
+ vfront-porch, vback-porch, vsync-len: vertical display timing parameters in
+ lines
+ - clock-frequency: display clock in Hz
+
+optional properties:
+ - hsync-active: hsync pulse is active low/high/ignored
+ - vsync-active: vsync pulse is active low/high/ignored
+ - de-active: data-enable pulse is active low/high/ignored
+ - pixelclk-active: with
+ - active high = drive pixel data on rising edge/
+ sample data on falling edge
+ - active low = drive pixel data on falling edge/
+ sample data on rising edge
+ - ignored = ignored
+ - interlaced (bool): boolean to enable interlaced mode
+ - doublescan (bool): boolean to enable doublescan mode
+
+All the optional properties that are not bool follow the following logic:
+ <1>: high active
+ <0>: low active
+ omitted: not used on hardware
+
+There are different ways of describing the capabilities of a display. The
+devicetree representation corresponds to the one commonly found in datasheets
+for displays. If a display supports multiple signal timings, the native-mode
+can be specified.
+
+The parameters are defined as:
+
+ +----------+-------------------------------------+----------+-------+
+ | | ↑ | | |
+ | | |vback_porch | | |
+ | | ↓ | | |
+ +----------#######################################----------+-------+
+ | # ↑ # | |
+ | # | # | |
+ | hback # | # hfront | hsync |
+ | porch # | hactive # porch | len |
+ |<-------->#<-------+--------------------------->#<-------->|<----->|
+ | # | # | |
+ | # |vactive # | |
+ | # | # | |
+ | # ↓ # | |
+ +----------#######################################----------+-------+
+ | | ↑ | | |
+ | | |vfront_porch | | |
+ | | ↓ | | |
+ +----------+-------------------------------------+----------+-------+
+ | | ↑ | | |
+ | | |vsync_len | | |
+ | | ↓ | | |
+ +----------+-------------------------------------+----------+-------+
+
+Example:
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 1080p24 {
+ /* 1920x1080p24 */
+ clock-frequency = <52000000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hfront-porch = <25>;
+ hback-porch = <25>;
+ hsync-len = <25>;
+ vback-porch = <2>;
+ vfront-porch = <2>;
+ vsync-len = <2>;
+ hsync-active = <1>;
+ };
+ };
+
+Every required property also supports the use of ranges, so the commonly used
+datasheet description with minimum, typical and maximum values can be used.
+
+Example:
+
+ timing1: timing {
+ /* 1920x1080p24 */
+ clock-frequency = <148500000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hsync-len = <0 44 60>;
+ hfront-porch = <80 88 95>;
+ hback-porch = <100 148 160>;
+ vfront-porch = <0 4 6>;
+ vback-porch = <0 36 50>;
+ vsync-len = <0 5 6>;
+ };
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2a23b18..c000f5a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -39,6 +39,21 @@ config DISPLAY_TIMING
config VIDEOMODE
bool
+config OF_DISPLAY_TIMING
+ bool "Enable device tree display timing support"
+ depends on OF
+ select DISPLAY_TIMING
+ help
+ helper to parse display timings from the devicetree
+
+config OF_VIDEOMODE
+ bool "Enable device tree videomode support"
+ depends on OF
+ select VIDEOMODE
+ select OF_DISPLAY_TIMING
+ help
+ helper to get videomodes from the devicetree
+
menuconfig FB
tristate "Support for frame buffer devices"
---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index fc30439..b936b00 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -168,4 +168,6 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
obj-$(CONFIG_VIDEOMODE) += videomode.o
+obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c
new file mode 100644
index 0000000..13ecd98
--- /dev/null
+++ b/drivers/video/of_display_timing.c
@@ -0,0 +1,239 @@
+/*
+ * OF helpers for parsing display timings
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * based on of_videomode.c by Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+
+/**
+ * parse_timing_property - parse timing_entry from device_node
+ * @np: device_node with the property
+ * @name: name of the property
+ * @result: will be set to the return value
+ *
+ * DESCRIPTION:
+ * Every display_timing can be specified with either just the typical value or
+ * a range consisting of min/typ/max. This function helps handling this
+ **/
+static int parse_timing_property(struct device_node *np, const char *name,
+ struct timing_entry *result)
+{
+ struct property *prop;
+ int length, cells, ret;
+
+ prop = of_find_property(np, name, &length);
+ if (!prop) {
+ pr_err("%s: could not find property %s\n",
+ of_node_full_name(np), name);
+ return -EINVAL;
+ }
+
+ cells = length / sizeof(u32);
+ if (cells = 1) {
+ ret = of_property_read_u32(np, name, &result->typ);
+ result->min = result->typ;
+ result->max = result->typ;
+ } else if (cells = 3) {
+ ret = of_property_read_u32_array(np, name, &result->min, cells);
+ } else {
+ pr_err("%s: illegal timing specification in %s\n",
+ of_node_full_name(np), name);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
+ * of_get_display_timing - parse display_timing entry from device_node
+ * @np: device_node with the properties
+ **/
+static struct display_timing *of_get_display_timing(struct device_node *np)
+{
+ struct display_timing *dt;
+ u32 val = 0;
+ int ret = 0;
+
+ dt = kzalloc(sizeof(*dt), GFP_KERNEL);
+ if (!dt) {
+ pr_err("%s: could not allocate display_timing struct\n",
+ of_node_full_name(np));
+ return NULL;
+ }
+
+ ret |= parse_timing_property(np, "hback-porch", &dt->hback_porch);
+ ret |= parse_timing_property(np, "hfront-porch", &dt->hfront_porch);
+ ret |= parse_timing_property(np, "hactive", &dt->hactive);
+ ret |= parse_timing_property(np, "hsync-len", &dt->hsync_len);
+ ret |= parse_timing_property(np, "vback-porch", &dt->vback_porch);
+ ret |= parse_timing_property(np, "vfront-porch", &dt->vfront_porch);
+ ret |= parse_timing_property(np, "vactive", &dt->vactive);
+ ret |= parse_timing_property(np, "vsync-len", &dt->vsync_len);
+ ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock);
+
+ dt->dmt_flags = 0;
+ dt->data_flags = 0;
+ if (!of_property_read_u32(np, "vsync-active", &val))
+ dt->dmt_flags |= val ? VESA_DMT_VSYNC_HIGH :
+ VESA_DMT_VSYNC_LOW;
+ if (!of_property_read_u32(np, "hsync-active", &val))
+ dt->dmt_flags |= val ? VESA_DMT_HSYNC_HIGH :
+ VESA_DMT_HSYNC_LOW;
+ if (!of_property_read_u32(np, "de-active", &val))
+ dt->data_flags |= val ? DISPLAY_FLAGS_DE_HIGH :
+ DISPLAY_FLAGS_DE_LOW;
+ if (!of_property_read_u32(np, "pixelclk-active", &val))
+ dt->data_flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+
+ if (of_property_read_bool(np, "interlaced"))
+ dt->data_flags |= DISPLAY_FLAGS_INTERLACED;
+ if (of_property_read_bool(np, "doublescan"))
+ dt->data_flags |= DISPLAY_FLAGS_DOUBLESCAN;
+
+ if (ret) {
+ pr_err("%s: error reading timing properties\n",
+ of_node_full_name(np));
+ kfree(dt);
+ return NULL;
+ }
+
+ return dt;
+}
+
+/**
+ * of_get_display_timings - parse all display_timing entries from a device_node
+ * @np: device_node with the subnodes
+ **/
+struct display_timings *of_get_display_timings(struct device_node *np)
+{
+ struct device_node *timings_np;
+ struct device_node *entry;
+ struct device_node *native_mode;
+ struct display_timings *disp;
+
+ if (!np) {
+ pr_err("%s: no devicenode given\n", of_node_full_name(np));
+ return NULL;
+ }
+
+ timings_np = of_find_node_by_name(np, "display-timings");
+ if (!timings_np) {
+ pr_err("%s: could not find display-timings node\n",
+ of_node_full_name(np));
+ return NULL;
+ }
+
+ disp = kzalloc(sizeof(*disp), GFP_KERNEL);
+ if (!disp) {
+ pr_err("%s: could not allocate struct disp'\n",
+ of_node_full_name(np));
+ goto dispfail;
+ }
+
+ entry = of_parse_phandle(timings_np, "native-mode", 0);
+ /* assume first child as native mode if none provided */
+ if (!entry)
+ entry = of_get_next_child(np, NULL);
+ /* if there is no child, it is useless to go on */
+ if (!entry) {
+ pr_err("%s: no timing specifications given\n",
+ of_node_full_name(np));
+ goto entryfail;
+ }
+
+ pr_debug("%s: using %s as default timing\n",
+ of_node_full_name(np), entry->name);
+
+ native_mode = entry;
+
+ disp->num_timings = of_get_child_count(timings_np);
+ if (disp->num_timings = 0) {
+ /* should never happen, as entry was already found above */
+ pr_err("%s: no timings specified\n", of_node_full_name(np));
+ goto entryfail;
+ }
+
+ disp->timings = kzalloc(sizeof(struct display_timing *) *
+ disp->num_timings, GFP_KERNEL);
+ if (!disp->timings) {
+ pr_err("%s: could not allocate timings array\n",
+ of_node_full_name(np));
+ goto entryfail;
+ }
+
+ disp->num_timings = 0;
+ disp->native_mode = 0;
+
+ for_each_child_of_node(timings_np, entry) {
+ struct display_timing *dt;
+
+ dt = of_get_display_timing(entry);
+ if (!dt) {
+ /*
+ * to not encourage wrong devicetrees, fail in case of
+ * an error
+ */
+ pr_err("%s: error in timing %d\n",
+ of_node_full_name(np), disp->num_timings + 1);
+ goto timingfail;
+ }
+
+ if (native_mode = entry)
+ disp->native_mode = disp->num_timings;
+
+ disp->timings[disp->num_timings] = dt;
+ disp->num_timings++;
+ }
+ of_node_put(timings_np);
+ /*
+ * native_mode points to the device_node returned by of_parse_phandle
+ * therefore call of_node_put on it
+ */
+ of_node_put(native_mode);
+
+ pr_debug("%s: got %d timings. Using timing #%d as default\n",
+ of_node_full_name(np), disp->num_timings,
+ disp->native_mode + 1);
+
+ return disp;
+
+timingfail:
+ if (native_mode)
+ of_node_put(native_mode);
+ display_timings_release(disp);
+entryfail:
+ kfree(disp);
+dispfail:
+ of_node_put(timings_np);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_get_display_timings);
+
+/**
+ * of_display_timings_exist - check if a display-timings node is provided
+ * @np: device_node with the timing
+ **/
+int of_display_timings_exist(struct device_node *np)
+{
+ struct device_node *timings_np;
+
+ if (!np)
+ return -EINVAL;
+
+ timings_np = of_parse_phandle(np, "display-timings", 0);
+ if (!timings_np)
+ return -EINVAL;
+
+ of_node_put(timings_np);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(of_display_timings_exist);
diff --git a/drivers/video/of_videomode.c b/drivers/video/of_videomode.c
new file mode 100644
index 0000000..5b8066c
--- /dev/null
+++ b/drivers/video/of_videomode.c
@@ -0,0 +1,54 @@
+/*
+ * generic videomode helper
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/of.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+/**
+ * of_get_videomode - get the videomode #<index> from devicetree
+ * @np - devicenode with the display_timings
+ * @vm - set to return value
+ * @index - index into list of display_timings
+ * (Set this to OF_USE_NATIVE_MODE to use whatever mode is
+ * specified as native mode in the DT.)
+ *
+ * DESCRIPTION:
+ * Get a list of all display timings and put the one
+ * specified by index into *vm. This function should only be used, if
+ * only one videomode is to be retrieved. A driver that needs to work
+ * with multiple/all videomodes should work with
+ * of_get_display_timings instead.
+ **/
+int of_get_videomode(struct device_node *np, struct videomode *vm,
+ int index)
+{
+ struct display_timings *disp;
+ int ret;
+
+ disp = of_get_display_timings(np);
+ if (!disp) {
+ pr_err("%s: no timings specified\n", of_node_full_name(np));
+ return -EINVAL;
+ }
+
+ if (index = OF_USE_NATIVE_MODE)
+ index = disp->native_mode;
+
+ ret = videomode_from_timing(disp, vm, index);
+ if (ret)
+ return ret;
+
+ display_timings_release(disp);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_videomode);
diff --git a/include/video/of_display_timing.h b/include/video/of_display_timing.h
new file mode 100644
index 0000000..8016eb7
--- /dev/null
+++ b/include/video/of_display_timing.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * display timings of helpers
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_DISPLAY_TIMING_H
+#define __LINUX_OF_DISPLAY_TIMING_H
+
+struct device_node;
+struct display_timings;
+
+#define OF_USE_NATIVE_MODE -1
+
+struct display_timings *of_get_display_timings(struct device_node *np);
+int of_display_timings_exist(struct device_node *np);
+
+#endif
diff --git a/include/video/of_videomode.h b/include/video/of_videomode.h
new file mode 100644
index 0000000..a07efcc
--- /dev/null
+++ b/include/video/of_videomode.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * videomode of-helpers
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_VIDEOMODE_H
+#define __LINUX_OF_VIDEOMODE_H
+
+struct device_node;
+struct videomode;
+
+int of_get_videomode(struct device_node *np, struct videomode *vm,
+ int index);
+
+#endif /* __LINUX_OF_VIDEOMODE_H */
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 4/7] fbmon: add videomode helpers
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Add a function to convert from the generic videomode to a fb_videomode.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/fbmon.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fb.h | 4 ++++
2 files changed, 56 insertions(+)
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index cef6557..17ce135 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <video/edid.h>
+#include <video/videomode.h>
#ifdef CONFIG_PPC_OF
#include <asm/prom.h>
#include <asm/pci-bridge.h>
@@ -1373,6 +1374,57 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
kfree(timings);
return err;
}
+
+#if IS_ENABLED(CONFIG_VIDEOMODE)
+int fb_videomode_from_videomode(const struct videomode *vm,
+ struct fb_videomode *fbmode)
+{
+ unsigned int htotal, vtotal;
+
+ fbmode->xres = vm->hactive;
+ fbmode->left_margin = vm->hback_porch;
+ fbmode->right_margin = vm->hfront_porch;
+ fbmode->hsync_len = vm->hsync_len;
+
+ fbmode->yres = vm->vactive;
+ fbmode->upper_margin = vm->vback_porch;
+ fbmode->lower_margin = vm->vfront_porch;
+ fbmode->vsync_len = vm->vsync_len;
+
+ /* prevent division by zero in KHZ2PICOS macro */
+ fbmode->pixclock = vm->pixelclock ?
+ KHZ2PICOS(vm->pixelclock / 1000) : 0;
+
+ fbmode->sync = 0;
+ fbmode->vmode = 0;
+ if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
+ fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
+ fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
+ fbmode->vmode |= FB_VMODE_INTERLACED;
+ if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
+ fbmode->vmode |= FB_VMODE_DOUBLE;
+ fbmode->flag = 0;
+
+ htotal = vm->hactive + vm->hfront_porch + vm->hback_porch +
+ vm->hsync_len;
+ vtotal = vm->vactive + vm->vfront_porch + vm->vback_porch +
+ vm->vsync_len;
+ /* prevent division by zero */
+ if (htotal && vtotal) {
+ fbmode->refresh = vm->pixelclock / (htotal * vtotal);
+ /* a mode must have htotal and vtotal != 0 or it is invalid */
+ } else {
+ fbmode->refresh = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
+#endif
+
#else
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c7a9571..100a176 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -19,6 +19,7 @@ struct vm_area_struct;
struct fb_info;
struct device;
struct file;
+struct videomode;
/* Definitions below are used in the parsed monitor specs */
#define FB_DPMS_ACTIVE_OFF 1
@@ -714,6 +715,9 @@ extern void fb_destroy_modedb(struct fb_videomode *modedb);
extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
+extern int fb_videomode_from_videomode(const struct videomode *vm,
+ struct fb_videomode *fbmode);
+
/* drivers/video/modedb.c */
#define VESA_MODEDB_SIZE 34
extern void fb_var_to_videomode(struct fb_videomode *mode,
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 5/7] fbmon: add of_videomode helpers
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Add helper to get fb_videomode from devicetree.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/fbmon.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/linux/fb.h | 4 ++++
2 files changed, 46 insertions(+)
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 17ce135..94ad0f7 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <video/edid.h>
+#include <video/of_videomode.h>
#include <video/videomode.h>
#ifdef CONFIG_PPC_OF
#include <asm/prom.h>
@@ -1425,6 +1426,47 @@ int fb_videomode_from_videomode(const struct videomode *vm,
EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
#endif
+#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
+static inline void dump_fb_videomode(const struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
+ m->xres, m->yres, m->refresh, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+
+/**
+ * of_get_fb_videomode - get a fb_videomode from devicetree
+ * @np: device_node with the timing specification
+ * @fb: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with of_get_display_timings ond
+ * work with that instead.
+ */
+int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
+ int index)
+{
+ struct videomode vm;
+ int ret;
+
+ ret = of_get_videomode(np, &vm, index);
+ if (ret)
+ return ret;
+
+ fb_videomode_from_videomode(&vm, fb);
+
+ pr_debug("%s: got %dx%d display mode from %s\n",
+ of_node_full_name(np), vm.hactive, vm.vactive, np->name);
+ dump_fb_videomode(fb);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_fb_videomode);
+#endif
+
#else
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 100a176..58b9860 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -20,6 +20,7 @@ struct fb_info;
struct device;
struct file;
struct videomode;
+struct device_node;
/* Definitions below are used in the parsed monitor specs */
#define FB_DPMS_ACTIVE_OFF 1
@@ -715,6 +716,9 @@ extern void fb_destroy_modedb(struct fb_videomode *modedb);
extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
+extern int of_get_fb_videomode(struct device_node *np,
+ struct fb_videomode *fb,
+ int index);
extern int fb_videomode_from_videomode(const struct videomode *vm,
struct fb_videomode *fbmode);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 6/7] drm_modes: add videomode helpers
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Add conversion from videomode to drm_display_mode
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/gpu/drm/drm_modes.c | 37 +++++++++++++++++++++++++++++++++++++
include/drm/drmP.h | 5 +++++
2 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 59450f3..184a22d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -35,6 +35,7 @@
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
+#include <video/videomode.h>
/**
* drm_mode_debug_printmodeline - debug print a mode
@@ -504,6 +505,42 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
}
EXPORT_SYMBOL(drm_gtf_mode);
+#if IS_ENABLED(CONFIG_VIDEOMODE)
+int drm_display_mode_from_videomode(const struct videomode *vm,
+ struct drm_display_mode *dmode)
+{
+ dmode->hdisplay = vm->hactive;
+ dmode->hsync_start = dmode->hdisplay + vm->hfront_porch;
+ dmode->hsync_end = dmode->hsync_start + vm->hsync_len;
+ dmode->htotal = dmode->hsync_end + vm->hback_porch;
+
+ dmode->vdisplay = vm->vactive;
+ dmode->vsync_start = dmode->vdisplay + vm->vfront_porch;
+ dmode->vsync_end = dmode->vsync_start + vm->vsync_len;
+ dmode->vtotal = dmode->vsync_end + vm->vback_porch;
+
+ dmode->clock = vm->pixelclock / 1000;
+
+ dmode->flags = 0;
+ if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
+ dmode->flags |= DRM_MODE_FLAG_PHSYNC;
+ else if (vm->dmt_flags & VESA_DMT_HSYNC_LOW)
+ dmode->flags |= DRM_MODE_FLAG_NHSYNC;
+ if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH)
+ dmode->flags |= DRM_MODE_FLAG_PVSYNC;
+ else if (vm->dmt_flags & VESA_DMT_VSYNC_LOW)
+ dmode->flags |= DRM_MODE_FLAG_NVSYNC;
+ if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
+ dmode->flags |= DRM_MODE_FLAG_INTERLACE;
+ if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
+ dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
+ drm_mode_set_name(dmode);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
+#endif
+
/**
* drm_mode_set_name - set the name on a mode
* @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3fd8280..5fbb0fe 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -85,6 +85,8 @@ struct module;
struct drm_file;
struct drm_device;
+struct videomode;
+
#include <drm/drm_os_linux.h>
#include <drm/drm_hashtab.h>
#include <drm/drm_mm.h>
@@ -1454,6 +1456,9 @@ extern struct drm_display_mode *
drm_mode_create_from_cmdline_mode(struct drm_device *dev,
struct drm_cmdline_mode *cmd);
+extern int drm_display_mode_from_videomode(const struct videomode *vm,
+ struct drm_display_mode *dmode);
+
/* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 7/7] drm_modes: add of_videomode helpers
From: Steffen Trumtrar @ 2012-12-18 16:57 UTC (permalink / raw)
To: devicestree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Add helper to get drm_display_mode from devicetree.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/gpu/drm/drm_modes.c | 33 +++++++++++++++++++++++++++++++++
include/drm/drmP.h | 4 ++++
2 files changed, 37 insertions(+)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 184a22d..fd53454 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -35,6 +35,7 @@
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
+#include <video/of_videomode.h>
#include <video/videomode.h>
/**
@@ -541,6 +542,38 @@ int drm_display_mode_from_videomode(const struct videomode *vm,
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
#endif
+#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
+/**
+ * of_get_drm_display_mode - get a drm_display_mode from devicetree
+ * @np: device_node with the timing specification
+ * @dmode: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with of_get_display_timings and
+ * work with that instead.
+ */
+int of_get_drm_display_mode(struct device_node *np,
+ struct drm_display_mode *dmode, int index)
+{
+ struct videomode vm;
+ int ret;
+
+ ret = of_get_videomode(np, &vm, index);
+ if (ret)
+ return ret;
+
+ drm_display_mode_from_videomode(&vm, dmode);
+
+ pr_debug("%s: got %dx%d display mode from %s\n",
+ of_node_full_name(np), vm.hactive, vm.vactive, np->name);
+ drm_mode_debug_printmodeline(dmode);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
+#endif
+
/**
* drm_mode_set_name - set the name on a mode
* @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 5fbb0fe..e26ca59 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -85,6 +85,7 @@ struct module;
struct drm_file;
struct drm_device;
+struct device_node;
struct videomode;
#include <drm/drm_os_linux.h>
@@ -1458,6 +1459,9 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
extern int drm_display_mode_from_videomode(const struct videomode *vm,
struct drm_display_mode *dmode);
+extern int of_get_drm_display_mode(struct device_node *np,
+ struct drm_display_mode *dmode,
+ int index);
/* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 0/7] of: add display helper
From: Steffen Trumtrar @ 2012-12-18 17:04 UTC (permalink / raw)
To: devicetree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355849873-8051-1-git-send-email-s.trumtrar@pengutronix.de>
Hi!
Finally, right in time before the end of the world on friday, v16 of the
display helpers.
Changes since v15:
- move include/linux/{videomode,display_timing}.h to include/video
- move include/linux/of_{videomode,display_timing}.h to include/video
- reimplement flags: add VESA flags and data flags
- let pixelclock in struct videomode be unsigned long
- rename of_display_timings_exists to of_display_timings_exist
- revise logging/error messages: replace __func__ with np->full_name
- rename pixelclk-inverted to pixelclk-active
- revise comments in code
Changes since v14:
- fix "const struct *" warning
(reported by: Leela Krishna Amudala <l.krishna@samsung.com>)
- return -EINVAL when htotal or vtotal are zero
- remove unreachable code in of_get_display_timings
- include headers in .c files and not implicit in .h
- sort includes alphabetically
- fix lower/uppercase in binding documentation
- rebase onto v3.7-rc7
Changes since v13:
- fix "const struct *" warning
(reported by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>)
- prevent division by zero in fb_videomode_from_videomode
Changes since v12:
- rename struct display_timing to via_display_timing in via subsystem
- fix refreshrate calculation
- fix "const struct *" warnings
(reported by: Manjunathappa, Prakash <prakash.pm@ti.com>)
- some CodingStyle fixes
- rewrite parts of commit messages and display-timings.txt
- let display_timing_get_value get all values instead of just typical
Changes since v11:
- make pointers const where applicable
- add reviewed-by Laurent Pinchart
Changes since v10:
- fix function name (drm_)display_mode_from_videomode
- add acked-by, reviewed-by, tested-by
Changes since v9:
- don't leak memory when previous timings were correct
- CodingStyle fixes
- move blank lines around
Changes since v8:
- fix memory leaks
- change API to be more consistent (foo_from_bar(struct bar, struct foo))
- include headers were necessary
- misc minor bugfixes
Changes since v7:
- move of_xxx to drivers/video
- remove non-binding documentation from display-timings.txt
- squash display_timings and videomode in one patch
- misc minor fixes
Changes since v6:
- get rid of some empty lines etc.
- move functions to their subsystems
- split of_ from non-of_ functions
- add at least some kerneldoc to some functions
Changes since v5:
- removed all display stuff and just describe timings
Changes since v4:
- refactored functions
Changes since v3:
- print error messages
- free alloced memory
- general cleanup
Changes since v2:
- use hardware-near property-names
- provide a videomode structure
- allow ranges for all properties (<min,typ,max>)
- functions to get display_mode or fb_videomode
Regards,
Steffen
Steffen Trumtrar (7):
viafb: rename display_timing to via_display_timing
video: add display_timing and videomode
video: add of helper for display timings/videomode
fbmon: add videomode helpers
fbmon: add of_videomode helpers
drm_modes: add videomode helpers
drm_modes: add of_videomode helpers
.../devicetree/bindings/video/display-timing.txt | 109 +++++++++
drivers/gpu/drm/drm_modes.c | 70 ++++++
drivers/video/Kconfig | 21 ++
drivers/video/Makefile | 4 +
drivers/video/display_timing.c | 24 ++
drivers/video/fbmon.c | 94 ++++++++
drivers/video/of_display_timing.c | 239 ++++++++++++++++++++
drivers/video/of_videomode.c | 54 +++++
drivers/video/via/hw.c | 6 +-
drivers/video/via/hw.h | 2 +-
drivers/video/via/lcd.c | 2 +-
drivers/video/via/share.h | 2 +-
drivers/video/via/via_modesetting.c | 8 +-
drivers/video/via/via_modesetting.h | 6 +-
drivers/video/videomode.c | 39 ++++
include/drm/drmP.h | 9 +
include/linux/fb.h | 8 +
include/video/display_timing.h | 124 ++++++++++
include/video/of_display_timing.h | 20 ++
include/video/of_videomode.h | 18 ++
include/video/videomode.h | 48 ++++
21 files changed, 894 insertions(+), 13 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/display-timing.txt
create mode 100644 drivers/video/display_timing.c
create mode 100644 drivers/video/of_display_timing.c
create mode 100644 drivers/video/of_videomode.c
create mode 100644 drivers/video/videomode.c
create mode 100644 include/video/display_timing.h
create mode 100644 include/video/of_display_timing.h
create mode 100644 include/video/of_videomode.h
create mode 100644 include/video/videomode.h
--
1.7.10.4
^ permalink raw reply
* [PATCHv16 1/7] viafb: rename display_timing to via_display_timing
From: Steffen Trumtrar @ 2012-12-18 17:04 UTC (permalink / raw)
To: devicetree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355850256-16135-1-git-send-email-s.trumtrar@pengutronix.de>
The struct display_timing is specific to the via subsystem. The naming leads to
collisions with the new struct display_timing, which is supposed to be a shared
struct between different subsystems.
To clean this up, prepend the existing struct with the subsystem it is specific
to.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/video/via/hw.c | 6 +++---
drivers/video/via/hw.h | 2 +-
drivers/video/via/lcd.c | 2 +-
drivers/video/via/share.h | 2 +-
drivers/video/via/via_modesetting.c | 8 ++++----
drivers/video/via/via_modesetting.h | 6 +++---
6 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 898590d..5563c67 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1467,10 +1467,10 @@ void viafb_set_vclock(u32 clk, int set_iga)
via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
}
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres)
{
- struct display_timing timing;
+ struct via_display_timing timing;
u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
timing.hor_addr = cxres;
@@ -1491,7 +1491,7 @@ struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga)
{
- struct display_timing crt_reg = var_to_timing(var,
+ struct via_display_timing crt_reg = var_to_timing(var,
cxres ? cxres : var->xres, cyres ? cyres : var->yres);
if (iga = IGA1)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 6be243c..c3f2572 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -637,7 +637,7 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
-struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
+struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres);
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 1650379..022b0df 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -549,7 +549,7 @@ void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
int panel_hres = plvds_setting_info->lcd_panel_hres;
int panel_vres = plvds_setting_info->lcd_panel_vres;
u32 clock;
- struct display_timing timing;
+ struct via_display_timing timing;
struct fb_var_screeninfo panel_var;
const struct fb_videomode *mode_crt_table, *panel_crt_table;
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 3158dfc..65c65c6 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -319,7 +319,7 @@ struct crt_mode_table {
int refresh_rate;
int h_sync_polarity;
int v_sync_polarity;
- struct display_timing crtc;
+ struct via_display_timing crtc;
};
struct io_reg {
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c
index 0e431ae..0b414b0 100644
--- a/drivers/video/via/via_modesetting.c
+++ b/drivers/video/via/via_modesetting.c
@@ -30,9 +30,9 @@
#include "debug.h"
-void via_set_primary_timing(const struct display_timing *timing)
+void via_set_primary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total / 8 - 5;
raw.hor_addr = timing->hor_addr / 8 - 1;
@@ -88,9 +88,9 @@ void via_set_primary_timing(const struct display_timing *timing)
via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
}
-void via_set_secondary_timing(const struct display_timing *timing)
+void via_set_secondary_timing(const struct via_display_timing *timing)
{
- struct display_timing raw;
+ struct via_display_timing raw;
raw.hor_total = timing->hor_total - 1;
raw.hor_addr = timing->hor_addr - 1;
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/via/via_modesetting.h
index 06e09fe..f6a6503 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/via/via_modesetting.h
@@ -33,7 +33,7 @@
#define VIA_PITCH_MAX 0x3FF8
-struct display_timing {
+struct via_display_timing {
u16 hor_total;
u16 hor_addr;
u16 hor_blank_start;
@@ -49,8 +49,8 @@ struct display_timing {
};
-void via_set_primary_timing(const struct display_timing *timing);
-void via_set_secondary_timing(const struct display_timing *timing);
+void via_set_primary_timing(const struct via_display_timing *timing);
+void via_set_secondary_timing(const struct via_display_timing *timing);
void via_set_primary_address(u32 addr);
void via_set_secondary_address(u32 addr);
void via_set_primary_pitch(u32 pitch);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv16 2/7] video: add display_timing and videomode
From: Steffen Trumtrar @ 2012-12-18 17:04 UTC (permalink / raw)
To: devicetree-discuss
Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
linux-media, Tomi Valkeinen, Stephen Warren, kernel,
Florian Tobias Schandinat, David Airlie, Rob Clark,
Leela Krishna Amudala
In-Reply-To: <1355850256-16135-1-git-send-email-s.trumtrar@pengutronix.de>
Add display_timing structure and the according helper functions. This allows
the description of a display via its supported timing parameters.
Also, add helper functions to convert from display timings to a generic videomode
structure.
The struct display_timing specifies all needed parameters to describe the signal
properties of a display in one mode. This includes
- ranges for signals that may have min-, max- and typical values
- single integers for signals that can be on, off or are ignored
- booleans for signals that are either on or off
As a display may support multiple modes like this, a struct display_timings is
added, that holds all given struct display_timing pointers and declares the
native mode of the display.
Although a display may state that a signal can be in a range, it is driven with
fixed values that indicate a videomode. Therefore graphic drivers don't need all
the information of struct display_timing, but would generate a videomode from
the given set of supported signal timings and work with that.
The video subsystems all define their own structs that describe a mode and work
with that (e.g. fb_videomode or drm_display_mode). To slowly replace all those
various structures and allow code reuse across those subsystems, add struct
videomode as a generic description.
This patch only includes the most basic fields in struct videomode. All missing
fields that are needed to have a really generic video mode description can be
added at a later stage.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/Kconfig | 6 ++
drivers/video/Makefile | 2 +
drivers/video/display_timing.c | 24 ++++++++
drivers/video/videomode.c | 39 +++++++++++++
include/video/display_timing.h | 124 ++++++++++++++++++++++++++++++++++++++++
include/video/videomode.h | 48 ++++++++++++++++
6 files changed, 243 insertions(+)
create mode 100644 drivers/video/display_timing.c
create mode 100644 drivers/video/videomode.c
create mode 100644 include/video/display_timing.h
create mode 100644 include/video/videomode.h
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d799..2a23b18 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -33,6 +33,12 @@ config VIDEO_OUTPUT_CONTROL
This framework adds support for low-level control of the video
output switch.
+config DISPLAY_TIMING
+ bool
+
+config VIDEOMODE
+ bool
+
menuconfig FB
tristate "Support for frame buffer devices"
---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..fc30439 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -167,3 +167,5 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_VIDEOMODE) += videomode.o
diff --git a/drivers/video/display_timing.c b/drivers/video/display_timing.c
new file mode 100644
index 0000000..5e1822c
--- /dev/null
+++ b/drivers/video/display_timing.c
@@ -0,0 +1,24 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <video/display_timing.h>
+
+void display_timings_release(struct display_timings *disp)
+{
+ if (disp->timings) {
+ unsigned int i;
+
+ for (i = 0; i < disp->num_timings; i++)
+ kfree(disp->timings[i]);
+ kfree(disp->timings);
+ }
+ kfree(disp);
+}
+EXPORT_SYMBOL_GPL(display_timings_release);
diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c
new file mode 100644
index 0000000..21c47a2
--- /dev/null
+++ b/drivers/video/videomode.c
@@ -0,0 +1,39 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <video/display_timing.h>
+#include <video/videomode.h>
+
+int videomode_from_timing(const struct display_timings *disp,
+ struct videomode *vm, unsigned int index)
+{
+ struct display_timing *dt;
+
+ dt = display_timings_get(disp, index);
+ if (!dt)
+ return -EINVAL;
+
+ vm->pixelclock = display_timing_get_value(&dt->pixelclock, TE_TYP);
+ vm->hactive = display_timing_get_value(&dt->hactive, TE_TYP);
+ vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, TE_TYP);
+ vm->hback_porch = display_timing_get_value(&dt->hback_porch, TE_TYP);
+ vm->hsync_len = display_timing_get_value(&dt->hsync_len, TE_TYP);
+
+ vm->vactive = display_timing_get_value(&dt->vactive, TE_TYP);
+ vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, TE_TYP);
+ vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP);
+ vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP);
+
+ vm->dmt_flags = dt->dmt_flags;
+ vm->data_flags = dt->data_flags;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_from_timing);
diff --git a/include/video/display_timing.h b/include/video/display_timing.h
new file mode 100644
index 0000000..71e9a38
--- /dev/null
+++ b/include/video/display_timing.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * description of display timings
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_DISPLAY_TIMING_H
+#define __LINUX_DISPLAY_TIMING_H
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+/* VESA display monitor timing parameters */
+#define VESA_DMT_HSYNC_LOW BIT(0)
+#define VESA_DMT_HSYNC_HIGH BIT(1)
+#define VESA_DMT_VSYNC_LOW BIT(2)
+#define VESA_DMT_VSYNC_HIGH BIT(3)
+
+/* display specific flags */
+#define DISPLAY_FLAGS_DE_LOW BIT(0) /* data enable flag */
+#define DISPLAY_FLAGS_DE_HIGH BIT(1)
+#define DISPLAY_FLAGS_PIXDATA_POSEDGE BIT(2) /* drive data on pos. edge */
+#define DISPLAY_FLAGS_PIXDATA_NEGEDGE BIT(3) /* drive data on neg. edge */
+#define DISPLAY_FLAGS_INTERLACED BIT(4)
+#define DISPLAY_FLAGS_DOUBLESCAN BIT(5)
+
+/*
+ * A single signal can be specified via a range of minimal and maximal values
+ * with a typical value, that lies somewhere inbetween.
+ */
+struct timing_entry {
+ u32 min;
+ u32 typ;
+ u32 max;
+};
+
+enum timing_entry_index {
+ TE_MIN = 0,
+ TE_TYP = 1,
+ TE_MAX = 2,
+};
+
+/*
+ * Single "mode" entry. This describes one set of signal timings a display can
+ * have in one setting. This struct can later be converted to struct videomode
+ * (see include/video/videomode.h). As each timing_entry can be defined as a
+ * range, one struct display_timing may become multiple struct videomodes.
+ *
+ * Example: hsync active high, vsync active low
+ *
+ * Active Video
+ * Video ______________________XXXXXXXXXXXXXXXXXXXXXX_____________________
+ * |<- sync ->|<- back ->|<----- active ----->|<- front ->|<- sync..
+ * | | porch | | porch |
+ *
+ * HSync _|¯¯¯¯¯¯¯¯¯¯|___________________________________________|¯¯¯¯¯¯¯¯¯
+ *
+ * VSync ¯|__________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_________
+ */
+struct display_timing {
+ struct timing_entry pixelclock;
+
+ struct timing_entry hactive; /* hor. active video */
+ struct timing_entry hfront_porch; /* hor. front porch */
+ struct timing_entry hback_porch; /* hor. back porch */
+ struct timing_entry hsync_len; /* hor. sync len */
+
+ struct timing_entry vactive; /* ver. active video */
+ struct timing_entry vfront_porch; /* ver. front porch */
+ struct timing_entry vback_porch; /* ver. back porch */
+ struct timing_entry vsync_len; /* ver. sync len */
+
+ unsigned int dmt_flags; /* VESA DMT flags */
+ unsigned int data_flags; /* video data flags */
+};
+
+/*
+ * This describes all timing settings a display provides.
+ * The native_mode is the default setting for this display.
+ * Drivers that can handle multiple videomodes should work with this struct and
+ * convert each entry to the desired end result.
+ */
+struct display_timings {
+ unsigned int num_timings;
+ unsigned int native_mode;
+
+ struct display_timing **timings;
+};
+
+/* get value specified by index from struct timing_entry */
+static inline u32 display_timing_get_value(const struct timing_entry *te,
+ enum timing_entry_index index)
+{
+ switch (index) {
+ case TE_MIN:
+ return te->min;
+ break;
+ case TE_TYP:
+ return te->typ;
+ break;
+ case TE_MAX:
+ return te->max;
+ break;
+ default:
+ return te->typ;
+ }
+}
+
+/* get one entry from struct display_timings */
+static inline struct display_timing *display_timings_get(const struct
+ display_timings *disp,
+ unsigned int index)
+{
+ if (disp->num_timings > index)
+ return disp->timings[index];
+ else
+ return NULL;
+}
+
+void display_timings_release(struct display_timings *disp);
+
+#endif
diff --git a/include/video/videomode.h b/include/video/videomode.h
new file mode 100644
index 0000000..a421562
--- /dev/null
+++ b/include/video/videomode.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * generic videomode description
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_VIDEOMODE_H
+#define __LINUX_VIDEOMODE_H
+
+#include <linux/types.h>
+#include <video/display_timing.h>
+
+/*
+ * Subsystem independent description of a videomode.
+ * Can be generated from struct display_timing.
+ */
+struct videomode {
+ unsigned long pixelclock; /* pixelclock in Hz */
+
+ u32 hactive;
+ u32 hfront_porch;
+ u32 hback_porch;
+ u32 hsync_len;
+
+ u32 vactive;
+ u32 vfront_porch;
+ u32 vback_porch;
+ u32 vsync_len;
+
+ unsigned int dmt_flags; /* VESA DMT flags */
+ unsigned int data_flags; /* video data flags */
+};
+
+/**
+ * videomode_from_timing - convert display timing to videomode
+ * @disp: structure with all possible timing entries
+ * @vm: return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function converts a struct display_timing to a struct videomode.
+ */
+int videomode_from_timing(const struct display_timings *disp,
+ struct videomode *vm, unsigned int index);
+
+#endif
--
1.7.10.4
^ 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