Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH 12/12] OMAPDSS: DPI: always use DSI PLL if available
From: Archit Taneja @ 2012-11-02 10:56 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob
In-Reply-To: <50939B84.6090602@ti.com>

On Friday 02 November 2012 03:38 PM, Tomi Valkeinen wrote:
> On 2012-10-31 09:26, Archit Taneja wrote:
>> On Tuesday 30 October 2012 09:40 PM, Tomi Valkeinen wrote:
>
>>> -    if (dpi_use_dsi_pll(dssdev)) {
>>> -        enum omap_dss_clk_source dispc_fclk_src >>> -            dssdev->clocks.dispc.dispc_fclk_src;
>>> -        dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
>>> +    /*
>>> +     * XXX We shouldn't need dssdev->channel for this. The dsi pll clock
>>> +     * source for DPI is SoC integration detail, not something that
>>> should
>>> +     * be configured in the dssdev
>>> +     */
>>
>> It is SoC integration detail, but it's flexible, it depends on which
>> manager is connected to DPI output. If it's connected to LCD1, the
>
> Hmm, yes, the comment is a bit misleading. The DSI PLL is not used for
> DPI, but for DISPC's LCD output. And DPI uses one of those LCD outputs.
>
>> source can be DSI1 PLL, if it's LCD2, it's source can be DSI2 PLL, if
>> it's connected to TV manager, it's source "has to be" HDMI PLL. And
>> these connections vary based on which OMAP revision we are on. We can
>> only be certain on OMAP3 that the source for DPI pixel clock can be
>> either PRCM or DSI PLL.
>
> On OMAP2 we can be certain the clock is PRCM =).
>
>> At the point of probe, we really don't know which manager is the DPI
>> output connected to. Hence, we sort of use dssdev->channel to make a
>> guess what manager we connect to in the future.
>
> Yep. My point was mainly that dssdev needs to go away, and we should
> somehow decide the used channel internally.
>
>> The right approach would be to figure this out at the time of enable,
>> where we know which manager the DPI output is connected to. We could
>> probably move the verification there too.
>
> Who chooses which manager to use for DPI?

If you are asking in terms of HW. The value in the DSS_CTRL bitfield 
decides which manager to use.

If you meant who/how should we choose this in software, then I don't 
know either.

>
> I'm not sure... I would really like to manage the basic setup, acquiring
> the resources, etc. at probe time, and enable would only enable the display.

One thing we could do is to grab all the possible resources that DPI can 
use for its pixel clock, and when it's enable time, see what all options 
it has. So, for example, for DPI on omap4, we could try to grab and 
verify all DSI PLL, HDMI PLL and PRCM. And then later choose the most 
appropriate one while enabling.

>
> That means that we should somehow get a manager for DPI at probe time,
> which may be a bit difficult, as we don't know what other displays there
> will be. So if, say, DPI can use LCD1 or LCD2, but DSI can only use
> LCD2, and at DPI's probe (presuming it's before DSI) we pick LCD2, DSI
> won't work.

Yes, it's not easy to know this at probe time. We could try to allocate 
resources at the time mgr->set_output() is called. We could have an 
output specific op. dss_mgr_set_output() could look like:

dss_mgr_set_output(mgr, output)
{
	/* Do the older stuff */
	...
	...

	output->get_and_config_resources(output);
}

In dpi.c:

dss_dpi_get_and_config_resources(output)
{
	switch (output->manager->id) {
	case LCD:
		Get DSI 1 PLL;
	case LCD2:
		Get DSI2 PLL;
	case TV:
		Get HDMI PLL;
	}

	/*
	 * Also set the DSS_CTRL bits here to tell which manager
	 * we need to connect to
	 */

	dss_select_dpi_manager(output->manager->id);
}

omapdss_output_ops dpi_ops = {
	.get_and_config_resources = dss_dpi_get_and_config_resources,
	...
};

However, even though this approach might be correct in the sense that we 
confiugre dpi when we know what manager we are connected to, I have to 
say that its not nice at all. Especially because setting manager output 
links is very omapdss-apply-ish. But I feel we would need to do 
something similar in omapdrm too.

>
> Anyway, while I'm not sure how to solve the above problem, I think we
> should improve our init a bit. For DPI there are the following steps
> done, in order:
>
> - DPI device added
> - DPI driver probe
> - DPI panel device added
> - DPI panel driver probe
>
> We currently add the panel device in DPI driver's probe, and figure out
> the DSI PLL at the same time. I think that should happen only when the
> panel driver probe happens. The panel driver should call something like
> dpi_get_output() or whatever, which acquires the DPI bus for the panel
> driver, and this would probably also choose the manager.

Hmm, that makes sense. Anyway, I don't think it's really bad if we refer 
to dssdev->channel for now.

I think we could have a clearer picture of this when we understand how 
omapdrm sets the links between its entities and how CPF would link the 
output-panel side of things.

Archit


^ permalink raw reply

* Re: [PATCH 12/12] OMAPDSS: DPI: always use DSI PLL if available
From: Archit Taneja @ 2012-11-02 11:21 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob
In-Reply-To: <5093A530.5050302@ti.com>

On Friday 02 November 2012 04:19 PM, Tomi Valkeinen wrote:
> On 2012-11-02 12:44, Archit Taneja wrote:
>
>> Hmm, that makes sense. Anyway, I don't think it's really bad if we refer
>> to dssdev->channel for now.
>
> It is, because dssdev->channel doesn't exist with DT.
>
> With DT we either need to figure out the channel in omapdss at runtime,
> or add a property to the DT data telling the channel. And adding such a
> property is not correct, as DT should be about describing the HW.

Ok.

I don't totally agree with your idea of figuring out the manager in 
panel the panel's probe. If it's done in the panel driver's probe 
itself, then by this point of time we have already set 
mgr->output->device links. If omapdss only does this stuff, then 
omapfb/omapdrm have just the job of connecting the overlays to the 
manager. Do you think that's okay?

Archit


^ permalink raw reply

* Re: [PATCH 12/12] OMAPDSS: DPI: always use DSI PLL if available
From: Tomi Valkeinen @ 2012-11-02 11:28 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob
In-Reply-To: <5093A9E8.70106@ti.com>

[-- Attachment #1: Type: text/plain, Size: 1948 bytes --]

On 2012-11-02 13:09, Archit Taneja wrote:
> On Friday 02 November 2012 04:19 PM, Tomi Valkeinen wrote:
>> On 2012-11-02 12:44, Archit Taneja wrote:
>>
>>> Hmm, that makes sense. Anyway, I don't think it's really bad if we refer
>>> to dssdev->channel for now.
>>
>> It is, because dssdev->channel doesn't exist with DT.
>>
>> With DT we either need to figure out the channel in omapdss at runtime,
>> or add a property to the DT data telling the channel. And adding such a
>> property is not correct, as DT should be about describing the HW.
> 
> Ok.
> 
> I don't totally agree with your idea of figuring out the manager in
> panel the panel's probe. If it's done in the panel driver's probe
> itself, then by this point of time we have already set
> mgr->output->device links. If omapdss only does this stuff, then

Hmm, I'm not sure I understand what's your point above? If figuring out
the mgr is done in panel's probe, the mgr->output link is not yet made
before that time.

> omapfb/omapdrm have just the job of connecting the overlays to the
> manager. Do you think that's okay?

Yes, that's how I think it should be. I don't see why omapfb/omapdrm
should care about which manager is being used for the output, it doesn't
really matter as long there is one and it works.

Then again, I don't have anything against omapfb/omapdrm choosing the
manager, but I don't see how they would have any better idea of which
manager to use than omapdss.

But as doing the connections at probe time is a bit problematic, perhaps
we should have a new step in this whole sequence. Something like
"connect" or whatever, which would lock the required blocks in the whole
pipeline, and acquire the required resources that couldn't be gotten at
probe time.

But even then, choosing the manager is not easy, as whoever chooses the
manager needs to observe all the possible displays used at the same time...

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [Qemu-devel] [PATCH] add bochs dispi interface framebuffer driver
From: Vasilis Liaskovitis @ 2012-11-02 11:53 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: linux-fbdev, qemu-devel
In-Reply-To: <5092797B.5090403@redhat.com>

On Thu, Nov 01, 2012 at 02:30:35PM +0100, Gerd Hoffmann wrote:
> On 10/19/12 12:35, Vasilis Liaskovitis wrote:
> > Hi,
> > 
> > On Thu, Mar 08, 2012 at 11:13:46AM +0100, Gerd Hoffmann wrote:
> >> This patchs adds a frame buffer driver for (virtual/emulated) vga cards
> >> implementing the bochs dispi interface.  Supported hardware are the
> >> bochs vga card with vbe extension and the qemu standard vga.
> >>
> >> The driver uses a fixed depth of 32bpp.  Otherwise it supports the full
> >> (but small) feature set of the bochs dispi interface:  Resolution
> >> switching and display panning.  It is tweaked to maximize fbcon speed,
> >> so you'll get the comfort of the framebuffer console in kvm guests
> >> without performance penalty.
> > 
> > I am testing this driver with qemu-kvm-1.2 or qemu-kvm master (commit)
> > and "-std vga". The driver works fine in general.
> > 
> > When I test a guest that runs X (ubuntu-12.04 desktop amd64), sometimes parts of
> > the screen and keyboard input is mixed between the X terminal and fbconsole
> > terminals. This happens only on the initial X11 login (right after boot or
> > reboot) and only sometimes.
> 
> Only with bochsfb or with vesafb (+ fbdev xorg driver) too?

vt-switching with vesafb/X11 works fine on a grml 64-bit image.  However, xorg
uses vesa driver in this case, not fbdev (fbdev / fbdevhw xorg modules are
initially loaded but then unloaded). X11 uses 1280x768 and vesafb uses 1024x768
according to dmesg. 

But i haven't been able to test ubuntu+vesafb.  Ubuntu kernels use efifb
(CONFIG_FB_EFI=y) and fbconsoles don't work at all with this driver +
qemu/seabios/vgastd.

I have tried using a custom kernel (CONFIG_FB_EFI not set, CONFIG_FB_VESA=y) but
for some reason I can't load vesafb on ubuntu desktop. No fb drivers are
blacklisted, but no fb driver is loaded if I specify a vga text mode with "vga="
in the kernel command line. X11 still uses 1280x768 resolution here.

Anyway, these are screenshots of the original problem (messed up output with
bochsfb + fbdev-xorg on ubuntu 12.04 startup): 

vt7 http://picpaste.de/bochsfb-badstart-AirrXZuF.png
vt1 http://www.picpaste.de/bochsfb-badstart-f1-EO10MVdF.png

it still happens with the latest bochsfb driver (tested with 3.6.0 though, not
3.7.0-rc3 yet)

> 
> > Xorg driver used is fbdev (i can send xorg log), not sure if another driver
> > should be used/implemented for the bochsfb.
> 
> Yes, that one is fine.
> 
> > CONFIG_FB_BOCHS=m
> > CONFIG_FB_VESA=y
> > # CONFIG_FB_EFI is not set
> > 
> > Should FB_VESA be turned to "not set" for this test? (it's not tristate in Kconfig)
> > 
> > Btw (slightly off-topic) are other framebuffer drivers suitable for the
> > standard qemu vga-pci device? Would vesafb or uvesafb work? 
> 
> Never tried uvesafb.  vesafb will work too, but run with a fixed
> resolution.  bochsfb allows you to change the display resolution at
> runtime using fbset.  fbcon is faster too because bochsfb supports
> display panning.

I assume bochsfb is the way we want to go. I can send more detailed info on the
uvesafb issue if needed.

thanks,

- Vasilis

^ permalink raw reply

* Re: [PATCH 12/12] OMAPDSS: DPI: always use DSI PLL if available
From: Archit Taneja @ 2012-11-02 11:56 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob
In-Reply-To: <5093AE79.9010603@ti.com>

On Friday 02 November 2012 04:58 PM, Tomi Valkeinen wrote:
> On 2012-11-02 13:09, Archit Taneja wrote:
>> On Friday 02 November 2012 04:19 PM, Tomi Valkeinen wrote:
>>> On 2012-11-02 12:44, Archit Taneja wrote:
>>>
>>>> Hmm, that makes sense. Anyway, I don't think it's really bad if we refer
>>>> to dssdev->channel for now.
>>>
>>> It is, because dssdev->channel doesn't exist with DT.
>>>
>>> With DT we either need to figure out the channel in omapdss at runtime,
>>> or add a property to the DT data telling the channel. And adding such a
>>> property is not correct, as DT should be about describing the HW.
>>
>> Ok.
>>
>> I don't totally agree with your idea of figuring out the manager in
>> panel the panel's probe. If it's done in the panel driver's probe
>> itself, then by this point of time we have already set
>> mgr->output->device links. If omapdss only does this stuff, then
>
> Hmm, I'm not sure I understand what's your point above? If figuring out
> the mgr is done in panel's probe, the mgr->output link is not yet made
> before that time.

My point is that we are trying to find a manager at panel's probe 
itself. It think that's what we do now. But one of your recent patch 
moves that to omapfb.

>
>> omapfb/omapdrm have just the job of connecting the overlays to the
>> manager. Do you think that's okay?
>
> Yes, that's how I think it should be. I don't see why omapfb/omapdrm
> should care about which manager is being used for the output, it doesn't
> really matter as long there is one and it works.
>
> Then again, I don't have anything against omapfb/omapdrm choosing the
> manager, but I don't see how they would have any better idea of which
> manager to use than omapdss.
>
> But as doing the connections at probe time is a bit problematic, perhaps
> we should have a new step in this whole sequence. Something like
> "connect" or whatever, which would lock the required blocks in the whole
> pipeline, and acquire the required resources that couldn't be gotten at
> probe time.
>
> But even then, choosing the manager is not easy, as whoever chooses the
> manager needs to observe all the possible displays used at the same time...

Right. I was wondering if omapfb/omapdrm could understand the 'all 
possible displays information' better compared to a panel's probe.

Even omapdrm/omafb can't be perfect because we could insert a panel 
driver module at any time, and omapfb/omapdrm may miss that out.

Archit


^ permalink raw reply

* Re: [Qemu-devel] [PATCH] add bochs dispi interface framebuffer driver
From: Gerd Hoffmann @ 2012-11-02 13:14 UTC (permalink / raw)
  To: Vasilis Liaskovitis; +Cc: linux-fbdev, qemu-devel
In-Reply-To: <20121102115346.GB20700@dhcp-192-168-178-175.profitbricks.localdomain>

>> Only with bochsfb or with vesafb (+ fbdev xorg driver) too?
> 
> vt-switching with vesafb/X11 works fine on a grml 64-bit image.  However, xorg
> uses vesa driver in this case, not fbdev (fbdev / fbdevhw xorg modules are
> initially loaded but then unloaded). X11 uses 1280x768 and vesafb uses 1024x768
> according to dmesg. 

You should be able to force the fbdev driver using xorg.conf.

> But i haven't been able to test ubuntu+vesafb.  Ubuntu kernels use efifb
> (CONFIG_FB_EFI=y) and fbconsoles don't work at all with this driver +
> qemu/seabios/vgastd.

I think this is a grub2 setup issue.  Grub2 can pass gfx mode params to
the linux kernel in a way efifb is able to handle.

> vt7 http://picpaste.de/bochsfb-badstart-AirrXZuF.png
> vt1 http://www.picpaste.de/bochsfb-badstart-f1-EO10MVdF.png

> it still happens with the latest bochsfb driver (tested with 3.6.0 though, not
> 3.7.0-rc3 yet)

Most likely this is a guest-side bug and not specific to bochsfb.
Console switching depends on all parties being cooperative.  Nothing
stops an application writing to the framebuffer even it isn't running on
the foreground console.

cheers,
  Gerd

^ permalink raw reply

* Re: [PATCH] video: exynos_dp: Clean up SW link training
From: Sean Paul @ 2012-11-02 14:45 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1351702475-31324-1-git-send-email-seanpaul@chromium.org>

On Thu, Nov 1, 2012 at 8:48 PM, Jingoo Han <jg1.han@samsung.com> wrote:
> On Friday, November 02, 2012 1:15 AM Sean Paul wrote
>>
>> On Thu, Nov 1, 2012 at 1:35 AM, Jingoo Han <jg1.han@samsung.com> wrote:
>> > On Thursday, November 01, 2012 1:55 AM Sean Paul wrote
>> >>
>> >> Clean up some of the SW training code to make it more clear and reduce
>> >> duplicate code.
>> >>
>> >> Signed-off-by: Sean Paul <seanpaul@chromium.org>
>> >> ---
>> >>  drivers/video/exynos/exynos_dp_core.c |  279 +++++++++++++--------------------
>> >>  1 files changed, 112 insertions(+), 167 deletions(-)
>> >>
>> >> Thanks for the pointer. There are still places where the code can be either
>> >> simplified, or duplication removed.
>> >
>> > Removing duplication is good, but don't change the Link training sequence.
>> > Link training sequence is very sensitive and tricky.
>> >
>>
>> I definitely appreciate how tricky it is :) I didn't actually change
>> any of the functionality from the original code.
>
> No, you changed the procedure when exynos_dp_clock_recovery_ok() fails.
> It is not the same with exynos_dp_get_adjust_training_lane().
> So, the else path at exynos_dp_process_clock_recovery() should not be
> changed.
>
>>
>> I noticed you made a couple of functional changes in your clean-up
>> patch (http://www.spinics.net/lists/linux-fbdev/msg06849.html). I
>> assumed that these functional changes were no-ops since bug fixes
>> would have gone in separate patches.
>>
>> I've also done a fair bit of testing to ensure it works.
>
> Yes, I know.
> But, most panels does NOT make the problem,
> even though there is a bug.
>
> With your panel, exynos_dp_clock_recovery_ok() does not fail,
> so, the problem does NOT happen.
>
>>
>> > I will modify your patch and I will submit new patch.
>> >
>>
>> More comments below.
>>
>> > Best regards,
>> > Jingoo Han
>> >
>> >>
>> >> Below is a rebased patch for your review.
>> >>
>> >> Sean
>> >>
>> >>
>> >> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
>> >> index 44820f2..b126e8a 100644
>> >> --- a/drivers/video/exynos/exynos_dp_core.c
>> >> +++ b/drivers/video/exynos/exynos_dp_core.c
>> >> @@ -276,7 +276,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
>> >>
>> >>       /* Set sink to D0 (Sink Not Ready) mode. */
>> >>       retval = exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
>> >> -                             DPCD_SET_POWER_STATE_D0);
>> >> +                     DPCD_SET_POWER_STATE_D0);
>> >>       if (retval)
>> >>               return retval;
>> >>
>> >> @@ -301,17 +301,18 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
>> >>       exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
>> >>
>> >>       /* Set RX training pattern */
>> >> -     exynos_dp_write_byte_to_dpcd(dp,
>> >> -             DPCD_ADDR_TRAINING_PATTERN_SET,
>> >> -             DPCD_SCRAMBLING_DISABLED |
>> >> -             DPCD_TRAINING_PATTERN_1);
>> >> +     retval = exynos_dp_write_byte_to_dpcd(dp,
>> >> +                     DPCD_ADDR_TRAINING_PATTERN_SET,
>> >> +                     DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
>> >> +     if (retval)
>> >> +             return retval;
>> >>
>> >>       for (lane = 0; lane < lane_count; lane++)
>> >>               buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
>> >>                           DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
>> >> -     retval = exynos_dp_write_bytes_to_dpcd(dp,
>> >> -             DPCD_ADDR_TRAINING_LANE0_SET,
>> >> -             lane_count, buf);
>> >> +
>> >> +     retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
>> >> +                     lane_count, buf);
>> >>
>> >>       return retval;
>> >>  }
>> >> @@ -337,18 +338,17 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
>> >>       return 0;
>> >>  }
>> >>
>> >> -static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
>> >> +static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
>> >> +             int lane_count)
>> >>  {
>> >>       int lane;
>> >> -     u8 lane_align;
>> >>       u8 lane_status;
>> >>
>> >> -     lane_align = link_align[2];
>> >> -     if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) = 0)
>> >> +     if ((link_align & DPCD_INTERLANE_ALIGN_DONE) = 0)
>> >>               return -EINVAL;
>> >>
>> >>       for (lane = 0; lane < lane_count; lane++) {
>> >> -             lane_status = exynos_dp_get_lane_status(link_align, lane);
>> >> +             lane_status = exynos_dp_get_lane_status(link_status, lane);
>> >>               lane_status &= DPCD_CHANNEL_EQ_BITS;
>> >>               if (lane_status != DPCD_CHANNEL_EQ_BITS)
>> >>                       return -EINVAL;
>> >> @@ -432,22 +432,47 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
>> >>       dp->link_train.lt_state = FAILED;
>> >>  }
>> >>
>> >> +static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
>> >> +                             u8 adjust_request[2])
>> >> +{
>> >> +     int lane, lane_count;
>> >> +     u8 voltage_swing, pre_emphasis, training_lane;
>> >> +
>> >> +     lane_count = dp->link_train.lane_count;
>> >> +     for (lane = 0; lane < lane_count; lane++) {
>> >> +             voltage_swing = exynos_dp_get_adjust_request_voltage(
>> >> +                                             adjust_request, lane);
>> >> +             pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> >> +                                             adjust_request, lane);
>> >> +             training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> >> +                             DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> >> +
>> >> +             if (voltage_swing = VOLTAGE_LEVEL_3)
>> >> +                     training_lane |= DPCD_MAX_SWING_REACHED;
>> >> +             if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
>> >> +                     training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> >> +
>> >> +             dp->link_train.training_lane[lane] = training_lane;
>> >> +     }
>> >> +}
>> >> +
>> >>  static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> >>  {
>> >> -     u8 link_status[2];
>> >>       int lane, lane_count, retval;
>> >> -
>> >> -     u8 adjust_request[2];
>> >> -     u8 voltage_swing;
>> >> -     u8 pre_emphasis;
>> >> -     u8 training_lane;
>> >> +     u8 voltage_swing, pre_emphasis, training_lane;
>> >> +     u8 link_status[2], adjust_request[2];
>> >>
>> >>       usleep_range(100, 101);
>> >>
>> >>       lane_count = dp->link_train.lane_count;
>> >>
>> >>       retval =  exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
>> >> -                             2, link_status);
>> >> +                     2, link_status);
>> >> +     if (retval)
>> >> +             return retval;
>> >> +
>> >> +     retval =  exynos_dp_read_bytes_from_dpcd(dp,
>> >> +                     DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
>> >>       if (retval)
>> >>               return retval;
>> >>
>> >> @@ -455,43 +480,9 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> >>               /* set training pattern 2 for EQ */
>> >>               exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
>> >>
>> >> -             for (lane = 0; lane < lane_count; lane++) {
>> >> -                     retval = exynos_dp_read_bytes_from_dpcd(dp,
>> >> -                                     DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
>> >> -                                     2, adjust_request);
>> >> -                     if (retval)
>> >> -                             return retval;
>> >> -
>> >> -                     voltage_swing = exynos_dp_get_adjust_request_voltage(
>> >> -                                                     adjust_request, lane);
>> >> -                     pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> >> -                                                     adjust_request, lane);
>> >> -                     training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> >> -                                     DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> >> -
>> >> -                     if (voltage_swing = VOLTAGE_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_SWING_REACHED;
>> >> -                     if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> >> -
>> >> -                     dp->link_train.training_lane[lane] = training_lane;
>> >> -
>> >> -                     exynos_dp_set_lane_link_training(dp,
>> >> -                             dp->link_train.training_lane[lane],
>> >> -                             lane);
>> >> -             }
>> >> -
>> >
>> > Please don't move it to back.
>> >
>>
>> I assume you're talking about the adjust_request read here? I noticed
>> this was changed in your original clean-up patch
>> (http://www.spinics.net/lists/linux-fbdev/msg06849.html), but assumed
>> it was a no-op. What bug does it fix? According to the flowcharts in
>> the exynos5250 datasheet (figure 49-10 & 49-11), this should be done
>> *before* setting training pattern 2. Your alteration to my patch will
>> read it after.
>>
>> I also noticed that you added back exynos_dp_get_adjust_training_lane
>> call here, along with setting DPCD_ADDR_TRAINING_LANE0_SET. You'll
>> notice that this same code is run in the else path of this function.
>
> No, it is not same.
>
> 1) your patch
>         exynos_dp_read_bytes_from_dpcd(dp,
>                 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
>         if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
>                 ...
>         } else {
>                 for (lane = 0; lane < lane_count; lane++) {
>                         training_lane = exynos_dp_get_lane_link_training()
>                         voltage_swing = exynos_dp_get_adjust_request_voltage()
>                         pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis()
>                         ...
>
> 2) my patch
>         if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
>                 ...
>         } else {
>                 for (lane = 0; lane < lane_count; lane++) {
>                         training_lane = exynos_dp_get_lane_link_training()
>                         exynos_dp_read_bytes_from_dpcd(dp,
>                                 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
>                         voltage_swing = exynos_dp_get_adjust_request_voltage()
>                         pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis()
>                         ...
>
>
> When the place of reading DPCD_ADDR_ADJUST_REQUEST_LANE0_1 is changed,
> it makes the Link Fail problem when exynos_dp_clock_recovery_ok() fails.
> In the case of most panels, exynos_dp_clock_recovery_ok() does not fail.
> But, some panels failed at exynos_dp_clock_recovery_ok(), and makes the problem
> if your patch is used.
>

I must be missing something. exynos_dp_clock_recovery_ok just
interprets link_status, which is read in the same place in both
patches. exynos_dp_get_lane_link_training reads from an exynos
register. I fail to see how either of those operations could affect
the adjust_request DPCD read.

The following is the order of operations for
exynos_dp_clock_recovery_ok failure with my patch:

(1) Read lane_status from DPCD
(2) Read adjust_request from DPCD
(3) clock_recovery_ok fails
(4) Get training_lane 0, parse voltage_swing 0 from adjust_request,
parse pre_emphasis 0 from adjust_request
(5) Check voltage_swing and pre_emphasis against training_lane,
increment loop count if nothing changed, exit earlyif max met
(6) Repeat (4),(5) for lane 1, 2, 3
(7) Change the value of training_lane to match adjust request read in step (2)
(8) Write training_ctl to exynos DP register (all lanes)
(9) Write training_lane back out to DPCD (all lanes)

With your patch (http://www.spinics.net/lists/linux-fbdev/msg08548.html):

(1) Read lane_status from DPCD
(2) clock_recovery_ok fails
(3) Get training_lane 0
(4) Read adjust_request from DPCD
(5) Parse voltage_swing 0 from adjust_request, parse pre_emphasis 0
from adjust_request
(6) Exit early if max met, check voltage_swing and pre_emphasis
against training_lane, increment loop count if nothing changed
(7) Change the value of training_lane to match adjust request read in step (4)
(8) Write training_ctl to exynos DP register for lane 0
(9) Repeat (3), (4), (5), (6), (7), (8) for lane 1, 2, 3
(9) Write training_lane back out to DPCD (all lanes)

So unless reading the training lane from DPCD or
exynos_dp_set_lane_link_training (which writes an exynos register)
changes the value of the adjust_request read from DPCD, our patches
are the same :)

> Also, your patch calls exynos_dp_get_adjust_request_voltage() and
> exynos_dp_get_adjust_request_pre_emphasis() twice,
> when exynos_dp_clock_recovery_ok() fails. Previously, exynos_dp_clock_recovery_ok()
> and exynos_dp_get_adjust_request_pre_emphasis() are called only onetime
> when exynos_dp_clock_recovery_ok() fails.
> There is no need to call exynos_dp_get_adjust_request_voltage() and
> exynos_dp_get_adjust_request_pre_emphasis() 'TWICE'.
>

Yes, it does, but it's just a shift and bitwise-AND... not really
heavy weight. It would be nice to refactor that code a bit to remove
the nasty, but that's a different patch.


>
> Anyway, your patch is good and readability is improved.
> So, I went the extra mile to accept your original patch and
> add it to v3 patch that I sent.
> (http://www.spinics.net/lists/linux-fbdev/msg08548.html)
>
> But, it is necessary to be careful with some error paths,
> that is not used at most eDP panels.
>

I'm still not convinced, but I think we're converging :)

Cheers,

Sean



> Best regards,
> Jingoo Han
>
>> Hence, I removed the duplication and put it all at the bottom. This
>> improves readability, matches the flowchart more closely, and removes
>> duplication.
>>
>> I'd urge you to please read my patch more carefully and ask questions
>> if you have any.
>>
>> Thanks!
>>
>> Sean
>>
>> >>               retval = exynos_dp_write_byte_to_dpcd(dp,
>> >>                       DPCD_ADDR_TRAINING_PATTERN_SET,
>> >> -                     DPCD_SCRAMBLING_DISABLED |
>> >> -                     DPCD_TRAINING_PATTERN_2);
>> >> -             if (retval)
>> >> -                     return retval;
>> >> -
>> >> -             retval = exynos_dp_write_bytes_to_dpcd(dp,
>> >> -                     DPCD_ADDR_TRAINING_LANE0_SET,
>> >> -                     lane_count,
>> >> -                     dp->link_train.training_lane);
>> >> +                     DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2);
>> >>               if (retval)
>> >>                       return retval;
>> >>
>> >> @@ -501,73 +492,49 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> >>               for (lane = 0; lane < lane_count; lane++) {
>> >>                       training_lane = exynos_dp_get_lane_link_training(
>> >>                                                       dp, lane);
>> >> -                     retval = exynos_dp_read_bytes_from_dpcd(dp,
>> >> -                                     DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
>> >> -                                     2, adjust_request);
>> >> -                     if (retval)
>> >> -                             return retval;
>> >> -
>> >>                       voltage_swing = exynos_dp_get_adjust_request_voltage(
>> >>                                                       adjust_request, lane);
>> >>                       pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> >>                                                       adjust_request, lane);
>> >>
>> >> -                     if (voltage_swing = VOLTAGE_LEVEL_3 ||
>> >> -                         pre_emphasis = PRE_EMPHASIS_LEVEL_3) {
>> >> -                             dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
>> >> -                             goto reduce_link_rate;
>> >> -                     }
>> >> -
>> >> -                     if ((DPCD_VOLTAGE_SWING_GET(training_lane) =
>> >> -                                     voltage_swing) &&
>> >> -                        (DPCD_PRE_EMPHASIS_GET(training_lane) =
>> >> -                                     pre_emphasis)) {
>> >> +                     if (DPCD_VOLTAGE_SWING_GET(training_lane) =
>> >> +                                     voltage_swing &&
>> >> +                         DPCD_PRE_EMPHASIS_GET(training_lane) =
>> >> +                                     pre_emphasis)
>> >>                               dp->link_train.cr_loop[lane]++;
>> >> -                             if (dp->link_train.cr_loop[lane] = MAX_CR_LOOP) {
>> >> -                                     dev_err(dp->dev, "CR Max loop\n");
>> >> -                                     goto reduce_link_rate;
>> >> -                             }
>> >> -                     }
>> >>
>> >> -                     training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> >> -                                     DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> >> -
>> >> -                     if (voltage_swing = VOLTAGE_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_SWING_REACHED;
>> >> -                     if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> >> -
>> >> -                     dp->link_train.training_lane[lane] = training_lane;
>> >> -
>> >> -                     exynos_dp_set_lane_link_training(dp,
>> >> -                             dp->link_train.training_lane[lane], lane);
>> >> +                     if (dp->link_train.cr_loop[lane] = MAX_CR_LOOP ||
>> >> +                         voltage_swing = VOLTAGE_LEVEL_3 ||
>> >> +                         pre_emphasis = PRE_EMPHASIS_LEVEL_3) {
>> >> +                             dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
>> >> +                                     dp->link_train.cr_loop[lane],
>> >> +                                     voltage_swing, pre_emphasis);
>> >> +                             exynos_dp_reduce_link_rate(dp);
>> >> +                             return -EIO;
>> >> +                     }
>> >>               }
>> >> +     }
>> >> +
>> >> +     exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> >>
>> >> -             retval = exynos_dp_write_bytes_to_dpcd(dp,
>> >> -                             DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
>> >> -                             dp->link_train.training_lane);
>> >> +     for (lane = 0; lane < lane_count; lane++) {
>> >> +             exynos_dp_set_lane_link_training(dp,
>> >> +                     dp->link_train.training_lane[lane], lane);
>> >> +             retval = exynos_dp_write_byte_to_dpcd(dp,
>> >> +                     DPCD_ADDR_TRAINING_LANE0_SET + lane,
>> >> +                     dp->link_train.training_lane[lane]);
>> >
>> > The following would be better.
>> > byte's'_to_dpcd is faster than byte_to_dpcd x 4 times.
>> >
>> >         for (lane = 0; lane < lane_count; lane++) {
>> >                 exynos_dp_set_lane_link_training(dp,
>> >                         dp->link_train.training_lane[lane], lane);
>> >         }
>> >
>> >         retval = exynos_dp_write_bytes_to_dpcd(dp,
>> >                         DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
>> >                         dp->link_train.training_lane);
>> >
>>
>>
>> Makes sense, that's a good change.
>>
>>
>> >>               if (retval)
>> >>                       return retval;
>> >>       }
>> >>
>> >>       return retval;
>> >> -
>> >> -reduce_link_rate:
>> >> -     exynos_dp_reduce_link_rate(dp);
>> >> -     return -EIO;
>> >>  }
>> >>
>> >>  static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
>> >>  {
>> >> -     u8 link_status[2];
>> >> -     u8 link_align[3];
>> >>       int lane, lane_count, retval;
>> >>       u32 reg;
>> >> -
>> >> -     u8 adjust_request[2];
>> >> -     u8 voltage_swing;
>> >> -     u8 pre_emphasis;
>> >> -     u8 training_lane;
>> >> +     u8 link_align, link_status[2], adjust_request[2];
>> >>
>> >>       usleep_range(400, 401);
>> >>
>> >> @@ -578,85 +545,63 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
>> >>       if (retval)
>> >>               return retval;
>> >>
>> >> -     if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
>> >> -             link_align[0] = link_status[0];
>> >> -             link_align[1] = link_status[1];
>> >> -
>> >> -             exynos_dp_read_byte_from_dpcd(dp,
>> >> -                     DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
>> >> -                     &link_align[2]);
>> >> -
>> >> -             for (lane = 0; lane < lane_count; lane++) {
>> >> -                     retval = exynos_dp_read_bytes_from_dpcd(dp,
>> >> -                                     DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
>> >> -                                     2, adjust_request);
>> >> -                     if (retval)
>> >> -                             return retval;
>> >> +     if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
>> >> +             exynos_dp_reduce_link_rate(dp);
>> >> +             return -EIO;
>> >> +     }
>> >>
>> >> -                     voltage_swing = exynos_dp_get_adjust_request_voltage(
>> >> -                                                     adjust_request, lane);
>> >> -                     pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
>> >> -                                                     adjust_request, lane);
>> >> -                     training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> >> -                                     DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>> >> +     retval = exynos_dp_read_bytes_from_dpcd(dp,
>> >> +                     DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
>> >> +     if (retval)
>> >> +             return retval;
>> >>
>> >> -                     if (voltage_swing = VOLTAGE_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_SWING_REACHED;
>> >> -                     if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
>> >> -                             training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
>> >> +     retval = exynos_dp_read_byte_from_dpcd(dp,
>> >> +                     DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
>> >> +     if (retval)
>> >> +             return retval;
>> >>
>> >> -                     dp->link_train.training_lane[lane] = training_lane;
>> >> -             }
>> >> +     exynos_dp_get_adjust_training_lane(dp, adjust_request);
>> >>
>> >> -             if (exynos_dp_channel_eq_ok(link_align, lane_count) = 0) {
>> >> -                     /* traing pattern Set to Normal */
>> >> -                     exynos_dp_training_pattern_dis(dp);
>> >> +     if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
>> >> +             /* traing pattern Set to Normal */
>> >> +             exynos_dp_training_pattern_dis(dp);
>> >>
>> >> -                     dev_info(dp->dev, "Link Training success!\n");
>> >> +             dev_info(dp->dev, "Link Training success!\n");
>> >>
>> >> -                     exynos_dp_get_link_bandwidth(dp, &reg);
>> >> -                     dp->link_train.link_rate = reg;
>> >> -                     dev_dbg(dp->dev, "final bandwidth = %.2x\n",
>> >> -                             dp->link_train.link_rate);
>> >> +             exynos_dp_get_link_bandwidth(dp, &reg);
>> >> +             dp->link_train.link_rate = reg;
>> >> +             dev_dbg(dp->dev, "final bandwidth = %.2x\n",
>> >> +                     dp->link_train.link_rate);
>> >>
>> >> -                     exynos_dp_get_lane_count(dp, &reg);
>> >> -                     dp->link_train.lane_count = reg;
>> >> -                     dev_dbg(dp->dev, "final lane count = %.2x\n",
>> >> -                             dp->link_train.lane_count);
>> >> +             exynos_dp_get_lane_count(dp, &reg);
>> >> +             dp->link_train.lane_count = reg;
>> >> +             dev_dbg(dp->dev, "final lane count = %.2x\n",
>> >> +                     dp->link_train.lane_count);
>> >>
>> >> -                     /* set enhanced mode if available */
>> >> -                     exynos_dp_set_enhanced_mode(dp);
>> >> -                     dp->link_train.lt_state = FINISHED;
>> >> -             } else {
>> >> -                     /* not all locked */
>> >> -                     dp->link_train.eq_loop++;
>> >> +             /* set enhanced mode if available */
>> >> +             exynos_dp_set_enhanced_mode(dp);
>> >> +             dp->link_train.lt_state = FINISHED;
>> >>
>> >> -                     if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
>> >> -                             dev_err(dp->dev, "EQ Max loop\n");
>> >> -                             goto reduce_link_rate;
>> >> -                     }
>> >> +             return 0;
>> >> +     }
>> >>
>> >> -                     for (lane = 0; lane < lane_count; lane++)
>> >> -                             exynos_dp_set_lane_link_training(dp,
>> >> -                                     dp->link_train.training_lane[lane],
>> >> -                                     lane);
>> >> +     /* not all locked */
>> >> +     dp->link_train.eq_loop++;
>> >>
>> >> -                     retval = exynos_dp_write_bytes_to_dpcd(dp,
>> >> -                                     DPCD_ADDR_TRAINING_LANE0_SET,
>> >> -                                     lane_count,
>> >> -                                     dp->link_train.training_lane);
>> >> -                     if (retval)
>> >> -                             return retval;
>> >> -             }
>> >> -     } else {
>> >> -             goto reduce_link_rate;
>> >> +     if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
>> >> +             dev_err(dp->dev, "EQ Max loop\n");
>> >> +             exynos_dp_reduce_link_rate(dp);
>> >> +             return -EIO;
>> >>       }
>> >>
>> >> -     return 0;
>> >> +     for (lane = 0; lane < lane_count; lane++)
>> >> +             exynos_dp_set_lane_link_training(dp,
>> >> +                     dp->link_train.training_lane[lane], lane);
>> >>
>> >> -reduce_link_rate:
>> >> -     exynos_dp_reduce_link_rate(dp);
>> >> -     return -EIO;
>> >> +     retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
>> >> +                     lane_count, dp->link_train.training_lane);
>> >> +
>> >> +     return retval;
>> >>  }
>> >>
>> >>  static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
>> >> --
>> >> 1.7.7.3
>> >
>

^ permalink raw reply

* Re: [PATCH v7 2/8] of: add helper to parse display timings
From: Leela Krishna Amudala @ 2012-11-02 17:31 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: devicetree-discuss, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1351675689-26814-3-git-send-email-s.trumtrar@pengutronix.de>

Hello Steffen,

On Wed, Oct 31, 2012 at 2:58 PM, Steffen Trumtrar
<s.trumtrar@pengutronix.de> wrote:
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
>  .../devicetree/bindings/video/display-timings.txt  |  139 +++++++++++++++
>  drivers/of/Kconfig                                 |    6 +
>  drivers/of/Makefile                                |    1 +
>  drivers/of/of_display_timings.c                    |  185 ++++++++++++++++++++
>  include/linux/of_display_timings.h                 |   20 +++
>  5 files changed, 351 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/video/display-timings.txt
>  create mode 100644 drivers/of/of_display_timings.c
>  create mode 100644 include/linux/of_display_timings.h
>
> diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt
> new file mode 100644
> index 0000000..04c94a3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/display-timings.txt
> @@ -0,0 +1,139 @@
> +display-timings 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.
> +
> +timings-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: displayclock 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-inverted : pixelclock is inverted/non-inverted/ignored
> + - interlaced (bool)
> + - doublescan (bool)
> +
> +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
> +
> +struct display_timing
> +=========> +
> +  +----------+---------------------------------------------+----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vback_porch                 |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------###############################################----------+-------+
> +  |          #                ↑                            #          |       |
> +  |          #                |                            #          |       |
> +  |  hback   #                |                            #  hfront  | hsync |
> +  |   porch  #                |       hactive              #  porch   |  len  |
> +  |<-------->#<---------------+--------------------------->#<-------->|<----->|
> +  |          #                |                            #          |       |
> +  |          #                |vactive                     #          |       |
> +  |          #                |                            #          |       |
> +  |          #                ↓                            #          |       |
> +  +----------###############################################----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vfront_porch                |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------+---------------------------------------------+----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vsync_len                   |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------+---------------------------------------------+----------+-------+
> +
> +
> +Example:
> +
> +       display-timings {
> +               native-mode = <&timing0>;
> +               timing0: 1920p24 {
> +                       /* 1920x1080p24 */
> +                       clock = <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 <min typ max>-tuples can be used.
> +
> +Example:
> +
> +       timing1: timing {
> +               /* 1920x1080p24 */
> +               clock = <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>;
> +       };
> +
> +
> +Usage in backend
> +========
> +
> +A backend driver may choose to use the display-timings directly and convert the timing
> +ranges to a suitable mode. Or it may just use the conversion of the display timings
> +to the required mode via the generic videomode struct.
> +
> +                                       dtb
> +                                        |
> +                                        |  of_get_display_timing_list
> +                                        ↓
> +                             struct display_timings
> +                                        |
> +                                        |  videomode_from_timing
> +                                        ↓
> +                           ---  struct videomode ---
> +                           |                       |
> + videomode_to_displaymode   |                      |   videomode_to_fb_videomode
> +                           ↓                       ↓
> +                    drm_display_mode         fb_videomode
> +
> +The functions of_get_fb_videomode and of_get_display_mode are provided
> +to conveniently get the respective mode representation from the devicetree.
> +
> +Conversion to videomode
> +===========> +
> +As device drivers normally work with some kind of video mode, the timings can be
> +converted (may be just a simple copying of the typical value) to a generic videomode
> +structure which then can be converted to the according mode used by the backend.
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index dfba3e6..781e773 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -83,4 +83,10 @@ config OF_MTD
>         depends on MTD
>         def_bool y
>
> +config OF_DISPLAY_TIMINGS
> +       def_bool y
> +       depends on DISPLAY_TIMING
> +       help
> +         helper to parse display timings from the devicetree
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index e027f44..c8e9603 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
>  obj-$(CONFIG_OF_PCI)   += of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)   += of_mtd.o
> +obj-$(CONFIG_OF_DISPLAY_TIMINGS) += of_display_timings.o
> diff --git a/drivers/of/of_display_timings.c b/drivers/of/of_display_timings.c
> new file mode 100644
> index 0000000..388fe4c
> --- /dev/null
> +++ b/drivers/of/of_display_timings.c
> @@ -0,0 +1,185 @@
> +/*
> + * 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/of.h>
> +#include <linux/slab.h>
> +#include <linux/export.h>
> +#include <linux/of_display_timings.h>
> +
> +/**
> + * parse_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_property(struct device_node *np, char *name,
> +                               struct timing_entry *result)
> +{
> +       struct property *prop;
> +       int length;
> +       int cells;
> +       int ret;
> +
> +       prop = of_find_property(np, name, &length);
> +       if (!prop) {
> +               pr_err("%s: could not find property %s\n", __func__, name);
> +               return -EINVAL;
> +       }
> +
> +       cells = length / sizeof(u32);
> +       if (cells = 1) {
> +               ret = of_property_read_u32_array(np, name, &result->typ, cells);

As you are reading only one vaue, you can use of_property_read_u32 instead.

> +               result->min = result->typ;
> +               result->max = result->typ;
> +       } else if (cells = 3) {
> +               ret = of_property_read_u32_array(np, name, &result->min, cells);

You are considering only min element, what about typ and max elements?

> +       } else {
> +               pr_err("%s: illegal timing specification in %s\n", __func__, name);
> +               return -EINVAL;
> +       }
> +
> +       return ret;
> +}
> +
> +/**
> + * of_get_display_timing - parse display_timing entry from device_node
> + * @np: device_node with the properties
> + **/
> +struct display_timing *of_get_display_timing(struct device_node *np)
> +{
> +       struct display_timing *dt;
> +       int ret = 0;
> +
> +       dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> +       if (!dt) {
> +               pr_err("%s: could not allocate display_timing struct\n", __func__);
> +               return NULL;
> +       }
> +
> +       ret |= parse_property(np, "hback-porch", &dt->hback_porch);
> +       ret |= parse_property(np, "hfront-porch", &dt->hfront_porch);
> +       ret |= parse_property(np, "hactive", &dt->hactive);
> +       ret |= parse_property(np, "hsync-len", &dt->hsync_len);
> +       ret |= parse_property(np, "vback-porch", &dt->vback_porch);
> +       ret |= parse_property(np, "vfront-porch", &dt->vfront_porch);
> +       ret |= parse_property(np, "vactive", &dt->vactive);
> +       ret |= parse_property(np, "vsync-len", &dt->vsync_len);
> +       ret |= parse_property(np, "clock-frequency", &dt->pixelclock);
> +
> +       of_property_read_u32(np, "vsync-active", &dt->vsync_pol_active);
> +       of_property_read_u32(np, "hsync-active", &dt->hsync_pol_active);
> +       of_property_read_u32(np, "de-active", &dt->de_pol_active);
> +       of_property_read_u32(np, "pixelclk-inverted", &dt->pixelclk_pol);
> +       dt->interlaced = of_property_read_bool(np, "interlaced");
> +       dt->doublescan = of_property_read_bool(np, "doublescan");
> +
> +       if (ret) {
> +               pr_err("%s: error reading timing properties\n", __func__);
> +               return NULL;
> +       }
> +
> +       return dt;
> +}
> +EXPORT_SYMBOL_GPL(of_get_display_timing);
> +
> +/**
> + * of_get_display_timing_list - parse all display_timing entries from a device_node
> + * @np: device_node with the subnodes
> + **/
> +struct display_timings *of_get_display_timing_list(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", __func__);
> +               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", __func__);
> +               return NULL;
> +       }
> +
> +       disp = kzalloc(sizeof(*disp), GFP_KERNEL);
> +
> +       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 (!entry) {
> +               pr_err("%s: no timing specifications given\n", __func__);
> +               return NULL;
> +       }
> +
> +       pr_info("%s: using %s as default timing\n", __func__, entry->name);
> +
> +       native_mode = entry;
> +
> +       disp->num_timings = of_get_child_count(timings_np);
> +       disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
> +                               GFP_KERNEL);
> +       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", __func__, disp->num_timings+1);
> +                       return NULL;
> +               }
> +
> +               if (native_mode = entry)
> +                       disp->native_mode = disp->num_timings;
> +
> +               disp->timings[disp->num_timings] = dt;
> +               disp->num_timings++;
> +       }
> +       of_node_put(timings_np);
> +
> +       if (disp->num_timings > 0)
> +               pr_info("%s: got %d timings. Using timing #%d as default\n", __func__,
> +                       disp->num_timings , disp->native_mode + 1);
> +       else {
> +               pr_err("%s: no valid timings specified\n", __func__);
> +               return NULL;
> +       }
> +       return disp;
> +}
> +EXPORT_SYMBOL_GPL(of_get_display_timing_list);
> +
> +/**
> + * of_display_timings_exists - check if a display-timings node is provided
> + * @np: device_node with the timing
> + **/
> +int of_display_timings_exists(struct device_node *np)
> +{
> +       struct device_node *timings_np;
> +       struct device_node *default_np;
> +
> +       if (!np)
> +               return -EINVAL;
> +
> +       timings_np = of_parse_phandle(np, "display-timings", 0);
> +       if (!timings_np)
> +               return -EINVAL;
> +
> +       return -EINVAL;

Here it should return success instead of -EINVAL.

And one query.. are the binding properties names and "display-timings"
node structure template  finalized..?

Best Wishes,
Leela Krishna Amudala.

> +}
> +EXPORT_SYMBOL_GPL(of_display_timings_exists);
> diff --git a/include/linux/of_display_timings.h b/include/linux/of_display_timings.h
> new file mode 100644
> index 0000000..e4e1f22
> --- /dev/null
> +++ b/include/linux/of_display_timings.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_TIMINGS_H
> +#define __LINUX_OF_DISPLAY_TIMINGS_H
> +
> +#include <linux/display_timing.h>
> +
> +#define OF_USE_NATIVE_MODE -1
> +
> +struct display_timings *of_get_display_timing_list(struct device_node *np);
> +struct display_timing *of_get_display_timing(struct device_node *np);
> +int of_display_timings_exists(struct device_node *np);
> +
> +#endif
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* video: exynos_dp: Reset and initialize DP before requesting irq
From: Ajay Kumar @ 2012-11-03  6:47 UTC (permalink / raw)
  To: linux-fbdev

If DP is not reset properly before kernel bootup(in bootloader code),
there can be few pending interrupts, and sometimes they invoke
DP irq handler as soon as the irq handler is registered in DP probe.
So, we make the DP driver more robust by resetting and
initializing DP at the earliest and then registering the irq handler.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
 drivers/video/exynos/exynos_dp_core.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..d241fd3 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -901,6 +901,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
 				"exynos-dp", dp);
 	if (ret) {
@@ -908,12 +914,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
-
-	exynos_dp_init_dp(dp);
-
 	ret = exynos_dp_detect_hpd(dp);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to detect hpd\n");
-- 
1.7.0.4


^ permalink raw reply related

* video: exynos_dp: Fix incorrect setting for INT_CTL
From: Ajay Kumar @ 2012-11-03  6:47 UTC (permalink / raw)
  To: linux-fbdev

INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
This patch fixes the wrong register setting for INT_CTL.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
 drivers/video/exynos/exynos_dp_reg.c |    2 +-
 drivers/video/exynos/exynos_dp_reg.h |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a..d67f49b 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
 void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
 {
 	/* Set interrupt pin assertion polarity as high */
-	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+	writel(INT_POL0 | INT_POL1, dp->reg_base + EXYNOS_DP_INT_CTL);
 
 	/* Clear pending regisers */
 	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014..fcf386e 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
 
 /* EXYNOS_DP_INT_CTL */
 #define SOFT_INT_CTRL				(0x1 << 2)
-#define INT_POL					(0x1 << 0)
+#define INT_POL0				(0x1 << 0)
+#define INT_POL1				(0x1 << 0)
 
 /* EXYNOS_DP_SYS_CTL_1 */
 #define DET_STA					(0x1 << 2)
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH v7 1/8] video: add display_timing struct and helpers
From: Steffen Trumtrar @ 2012-11-04 16:53 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-fbdev, devicetree-discuss, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, kernel, Guennady Liakhovetski, linux-media
In-Reply-To: <20121101200842.GA13137@avionic-0098.mockup.avionic-design.de>

On Thu, Nov 01, 2012 at 09:08:42PM +0100, Thierry Reding wrote:
> On Wed, Oct 31, 2012 at 10:28:01AM +0100, Steffen Trumtrar wrote:
> [...]
> > +void timings_release(struct display_timings *disp)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < disp->num_timings; i++)
> > +		kfree(disp->timings[i]);
> > +}
> > +
> > +void display_timings_release(struct display_timings *disp)
> > +{
> > +	timings_release(disp);
> > +	kfree(disp->timings);
> > +}
> 
> I'm not quite sure I understand how these are supposed to be used. The
> only use-case where a struct display_timings is dynamically allocated is
> for the OF helpers. In that case, wouldn't it be more useful to have a
> function that frees the complete structure, including the struct
> display_timings itself? Something like this, which has all of the above
> rolled into one:
> 
> 	void display_timings_free(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);
> 	}
> 

Well, you are right. They can be rolled into one function.
The extra function call is useless and as it seems confusing.

Regards,
Steffen

> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* Re: [PATCH v7 2/8] of: add helper to parse display timings
From: Steffen Trumtrar @ 2012-11-04 17:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Tomi Valkeinen,
	Laurent Pinchart, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	Guennady Liakhovetski, linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20121101201510.GB13137-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>

On Thu, Nov 01, 2012 at 09:15:10PM +0100, Thierry Reding wrote:
> On Wed, Oct 31, 2012 at 10:28:02AM +0100, Steffen Trumtrar wrote:
> [...]
> > diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt
> [...]
> > @@ -0,0 +1,139 @@
> > +display-timings bindings
> > +=========
> > +
> > +display-timings-node
> > +------------
> 
> Maybe extend the underline to the length of the section and subsection
> titles respectively?
> 
> > +struct display_timing
> > +=========> 
> Same here.
> 
> > +config OF_DISPLAY_TIMINGS
> > +	def_bool y
> > +	depends on DISPLAY_TIMING
> 
> Maybe this should be called OF_DISPLAY_TIMING to match DISPLAY_TIMING,
> or rename DISPLAY_TIMING to DISPLAY_TIMINGS for the sake of consistency?
> 

Yes, to all three above.

> > +/**
> > + * of_get_display_timing_list - parse all display_timing entries from a device_node
> > + * @np: device_node with the subnodes
> > + **/
> > +struct display_timings *of_get_display_timing_list(struct device_node *np)
> 
> Perhaps this would better be named of_get_display_timings() to match the
> return type?
> 

Hm, I'm not really sure about that. I found it to error prone, to have a function
of_get_display_timing and of_get_display_timings. That's why I chose
of_get_display_timing_list. But you are correct, that it doesn't match the return
value. Maybe I should just make the first function static and change the name as you
suggested.

> > +	disp = kzalloc(sizeof(*disp), GFP_KERNEL);
> 
> Shouldn't you be checking this for allocation failures?
> 
> > +	disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
> > +				GFP_KERNEL);
> 
> Same here.
> 

Yes, to both.

Regards,
Steffen


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* Re: [PATCH v7 2/8] of: add helper to parse display timings
From: Steffen Trumtrar @ 2012-11-04 17:23 UTC (permalink / raw)
  To: Leela Krishna Amudala
  Cc: devicetree-discuss, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <CAL1wa8dGiS-UDk7vjPKBaxQHB2FyNgLRYr5jsJZe4GjdzHELLQ@mail.gmail.com>

Hi!

On Fri, Nov 02, 2012 at 10:49:47PM +0530, Leela Krishna Amudala wrote:
> Hello Steffen,
> 
> On Wed, Oct 31, 2012 at 2:58 PM, Steffen Trumtrar
> > +static int parse_property(struct device_node *np, char *name,
> > +                               struct timing_entry *result)
> > +{
> > +       struct property *prop;
> > +       int length;
> > +       int cells;
> > +       int ret;
> > +
> > +       prop = of_find_property(np, name, &length);
> > +       if (!prop) {
> > +               pr_err("%s: could not find property %s\n", __func__, name);
> > +               return -EINVAL;
> > +       }
> > +
> > +       cells = length / sizeof(u32);
> > +       if (cells = 1) {
> > +               ret = of_property_read_u32_array(np, name, &result->typ, cells);
> 
> As you are reading only one vaue, you can use of_property_read_u32 instead.
> 

Yes, thats copypasta, no need for _array here.

> > +               result->min = result->typ;
> > +               result->max = result->typ;
> > +       } else if (cells = 3) {
> > +               ret = of_property_read_u32_array(np, name, &result->min, cells);
> 
> You are considering only min element, what about typ and max elements?
> 

I start at the address of result->min and read three u32-values, therefore all
three (min,typ,max) are filled with values.

> > +
> > +/**
> > + * of_display_timings_exists - check if a display-timings node is provided
> > + * @np: device_node with the timing
> > + **/
> > +int of_display_timings_exists(struct device_node *np)
> > +{
> > +       struct device_node *timings_np;
> > +       struct device_node *default_np;
> > +
> > +       if (!np)
> > +               return -EINVAL;
> > +
> > +       timings_np = of_parse_phandle(np, "display-timings", 0);
> > +       if (!timings_np)
> > +               return -EINVAL;
> > +
> > +       return -EINVAL;
> 
> Here it should return success instead of -EINVAL.
> 

Yes.

> And one query.. are the binding properties names and "display-timings"
> node structure template  finalized..?
> 

I sure hope so. There actually is one error in the examples though.
The property clock is called clock-frequency. I included it correctly
at the top of display-timings.txt, but overlooked it in the examples.

Regards,
Steffen

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* Re: video: exynos_dp: Fix incorrect setting for INT_CTL
From: Jingoo Han @ 2012-11-05  2:28 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1351926402-25484-2-git-send-email-ajaykumar.rs@samsung.com>

On Saturday, November 03, 2012 4:07 PM Ajay Kumar wrote
> Subject: video: exynos_dp: Fix incorrect setting for INT_CTL

Please don't forget to add "[PATCH] " as below.

[PATCH] video: exynos_dp: Fix incorrect setting for INT_CTL

> 
> INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
> This patch fixes the wrong register setting for INT_CTL.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/video/exynos/exynos_dp_reg.c |    2 +-
>  drivers/video/exynos/exynos_dp_reg.h |    3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
> index 3f5ca8a..d67f49b 100644
> --- a/drivers/video/exynos/exynos_dp_reg.c
> +++ b/drivers/video/exynos/exynos_dp_reg.c
> @@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
>  void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
>  {
>  	/* Set interrupt pin assertion polarity as high */
> -	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
> +	writel(INT_POL0 | INT_POL1, dp->reg_base + EXYNOS_DP_INT_CTL);
> 
>  	/* Clear pending regisers */
>  	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
> diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
> index 1f2f014..fcf386e 100644
> --- a/drivers/video/exynos/exynos_dp_reg.h
> +++ b/drivers/video/exynos/exynos_dp_reg.h
> @@ -242,7 +242,8 @@
> 
>  /* EXYNOS_DP_INT_CTL */
>  #define SOFT_INT_CTRL				(0x1 << 2)
> -#define INT_POL					(0x1 << 0)
> +#define INT_POL0				(0x1 << 0)
> +#define INT_POL1				(0x1 << 0)

Why are the bit definitions the same???
INT_POL1 uses 1st bit of DP_INT_CTL register.

Please fix this bug as below.

#define INT_POL1				(0x1 << 1)
#define INT_POL0				(0x1 << 0)

Ajay,
please don't make careless mistake.
I don't want to waste my time.


> 
>  /* EXYNOS_DP_SYS_CTL_1 */
>  #define DET_STA					(0x1 << 2)
> --
> 1.7.0.4


^ permalink raw reply

* Re: video: exynos_dp: Reset and initialize DP before requesting irq
From: Jingoo Han @ 2012-11-05  2:47 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1351926402-25484-1-git-send-email-ajaykumar.rs@samsung.com>

On Saturday, November 03, 2012 4:07 PM Ajay Kumar wrote
> Subject: video: exynos_dp: Reset and initialize DP before requesting irq

Please don't forget to add "[PATCH] " as below.

[PATCH] video: exynos_dp: Reset and initialize DP before requesting irq

> 
> If DP is not reset properly before kernel bootup(in bootloader code),
> there can be few pending interrupts, and sometimes they invoke
> DP irq handler as soon as the irq handler is registered in DP probe.
> So, we make the DP driver more robust by resetting and
> initializing DP at the earliest and then registering the irq handler.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>

Acked-by: Jingoo Han <jg1.han@samsung.com>

Tested with Exynos5250.

> ---
>  drivers/video/exynos/exynos_dp_core.c |   12 ++++++------
>  1 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index d55470e..d241fd3 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -901,6 +901,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
> 
> +	dp->video_info = pdata->video_info;
> +	if (pdata->phy_init)
> +		pdata->phy_init();
> +
> +	exynos_dp_init_dp(dp);
> +
>  	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
>  				"exynos-dp", dp);
>  	if (ret) {
> @@ -908,12 +914,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>  		return ret;
>  	}
> 
> -	dp->video_info = pdata->video_info;
> -	if (pdata->phy_init)
> -		pdata->phy_init();
> -
> -	exynos_dp_init_dp(dp);
> -
>  	ret = exynos_dp_detect_hpd(dp);
>  	if (ret) {
>  		dev_err(&pdev->dev, "unable to detect hpd\n");
> --
> 1.7.0.4


^ permalink raw reply

* Re: [PATCH] pwm-backlight: Pinctrl-fy
From: Thierry Reding @ 2012-11-05  7:33 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Richard Purdie, Florian Tobias Schandinat, linux-fbdev,
	linux-kernel, Koen Kooi, Matt Porter, Russ Dill, linux-omap
In-Reply-To: <1351699047-4487-1-git-send-email-panto@antoniou-consulting.com>

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

On Wed, Oct 31, 2012 at 05:57:27PM +0200, Pantelis Antoniou wrote:
[...]
> diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
[...]
> @@ -20,6 +20,8 @@
>  #include <linux/pwm.h>
>  #include <linux/pwm_backlight.h>
>  #include <linux/slab.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <linux/err.h>

linux/err.h is already included earlier.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH V2] video: exynos_dp: Fix incorrect setting for INT_CTL
From: Jingoo Han @ 2012-11-05  7:38 UTC (permalink / raw)
  To: linux-fbdev

On Monday, November 05, 2012 4:43 PM Ajay Kumar wrote
> 
> INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
> This patch fixes the wrong register setting for INT_CTL.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/video/exynos/exynos_dp_reg.c |    2 +-
>  drivers/video/exynos/exynos_dp_reg.h |    3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
> index 3f5ca8a..d67f49b 100644
> --- a/drivers/video/exynos/exynos_dp_reg.c
> +++ b/drivers/video/exynos/exynos_dp_reg.c
> @@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
>  void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
>  {
>  	/* Set interrupt pin assertion polarity as high */
> -	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
> +	writel(INT_POL0 | INT_POL1, dp->reg_base + EXYNOS_DP_INT_CTL);
> 
>  	/* Clear pending regisers */
>  	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
> diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
> index 1f2f014..8548b91 100644
> --- a/drivers/video/exynos/exynos_dp_reg.h
> +++ b/drivers/video/exynos/exynos_dp_reg.h
> @@ -242,7 +242,8 @@
> 
>  /* EXYNOS_DP_INT_CTL */
>  #define SOFT_INT_CTRL				(0x1 << 2)
> -#define INT_POL					(0x1 << 0)
> +#define INT_POL0				(0x1 << 0)
> +#define INT_POL1				(0x1 << 1)

Please keep the bit order in descending order, for readability.
It is not big deal, so I will send the v3 patch, soon.


> 
>  /* EXYNOS_DP_SYS_CTL_1 */
>  #define DET_STA					(0x1 << 2)
> --
> 1.7.0.4


^ permalink raw reply

* [PATCH v3 1/2] video: exynos_dp: Reset and initialize DP before requesting irq
From: Jingoo Han @ 2012-11-05  7:43 UTC (permalink / raw)
  To: linux-fbdev

If DP is not reset properly before kernel bootup(in bootloader code),
there can be few pending interrupts, and sometimes they invoke
DP irq handler as soon as the irq handler is registered in DP probe.
So, we make the DP driver more robust by resetting and
initializing DP at the earliest and then registering the irq handler.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Tested with Exynos5250

 drivers/video/exynos/exynos_dp_core.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..d241fd3 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -901,6 +901,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
 				"exynos-dp", dp);
 	if (ret) {
@@ -908,12 +914,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
-
-	exynos_dp_init_dp(dp);
-
 	ret = exynos_dp_detect_hpd(dp);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to detect hpd\n");
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 2/2] video: exynos_dp: Fix incorrect setting for INT_CTL
From: Jingoo Han @ 2012-11-05  7:44 UTC (permalink / raw)
  To: linux-fbdev

INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
This patch fixes the wrong register setting for INT_CTL.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Tested with Exynos5250

 drivers/video/exynos/exynos_dp_reg.c |    2 +-
 drivers/video/exynos/exynos_dp_reg.h |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a..cc7765f 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
 void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
 {
 	/* Set interrupt pin assertion polarity as high */
-	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+	writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
 
 	/* Clear pending regisers */
 	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014..2e9bd0e 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
 
 /* EXYNOS_DP_INT_CTL */
 #define SOFT_INT_CTRL				(0x1 << 2)
-#define INT_POL					(0x1 << 0)
+#define INT_POL1				(0x1 << 1)
+#define INT_POL0				(0x1 << 0)
 
 /* EXYNOS_DP_SYS_CTL_1 */
 #define DET_STA					(0x1 << 2)
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 1/2] video: exynos_dp: Reset and initialize DP before requesting irq
From: Jingoo Han @ 2012-11-05  7:51 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <003301cdbb29$421e2ee0$c65a8ca0$%han@samsung.com>

From: Ajay Kumar <ajaykumar.rs@samsung.com>

If DP is not reset properly before kernel bootup(in bootloader code),
there can be few pending interrupts, and sometimes they invoke
DP irq handler as soon as the irq handler is registered in DP probe.
So, we make the DP driver more robust by resetting and
initializing DP at the earliest and then registering the irq handler.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Added 'From: Ajay Kumar <ajaykumar.rs@samsung.com>'

 drivers/video/exynos/exynos_dp_core.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..d241fd3 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -901,6 +901,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
 				"exynos-dp", dp);
 	if (ret) {
@@ -908,12 +914,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
-
-	exynos_dp_init_dp(dp);
-
 	ret = exynos_dp_detect_hpd(dp);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to detect hpd\n");
-- 
1.7.1




^ permalink raw reply related

* [PATCH v3 2/2] video: exynos_dp: Fix incorrect setting for INT_CTL
From: Jingoo Han @ 2012-11-05  7:52 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <003401cdbb29$60b46220$221d2660$%han@samsung.com>

From: Ajay Kumar <ajaykumar.rs@samsung.com>

INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
This patch fixes the wrong register setting for INT_CTL.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Added 'From: Ajay Kumar <ajaykumar.rs@samsung.com>'

 drivers/video/exynos/exynos_dp_reg.c |    2 +-
 drivers/video/exynos/exynos_dp_reg.h |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a..cc7765f 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
 void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
 {
 	/* Set interrupt pin assertion polarity as high */
-	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+	writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
 
 	/* Clear pending regisers */
 	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014..2e9bd0e 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
 
 /* EXYNOS_DP_INT_CTL */
 #define SOFT_INT_CTRL				(0x1 << 2)
-#define INT_POL					(0x1 << 0)
+#define INT_POL1				(0x1 << 1)
+#define INT_POL0				(0x1 << 0)
 
 /* EXYNOS_DP_SYS_CTL_1 */
 #define DET_STA					(0x1 << 2)
-- 
1.7.1



^ permalink raw reply related

* [PATCH V2] video: exynos_dp: Reset and initialize DP before requesting irq
From: Ajay Kumar @ 2012-11-05  7:54 UTC (permalink / raw)
  To: linux-fbdev

If DP is not reset properly before kernel bootup(in bootloader code),
there can be few pending interrupts, and sometimes they invoke
DP irq handler as soon as the irq handler is registered in DP probe.
So, we make the DP driver more robust by resetting and
initializing DP at the earliest and then registering the irq handler.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/exynos/exynos_dp_core.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..d241fd3 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -901,6 +901,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
 				"exynos-dp", dp);
 	if (ret) {
@@ -908,12 +914,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
-
-	exynos_dp_init_dp(dp);
-
 	ret = exynos_dp_detect_hpd(dp);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to detect hpd\n");
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH V2] video: exynos_dp: Fix incorrect setting for INT_CTL
From: Ajay Kumar @ 2012-11-05  7:54 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <002901cdbb28$82ecb7d0$88c62770$%han@samsung.com>

INT_CTL register contains bits INT_POL0 and INT_POL1, and not INT_POL.
This patch fixes the wrong register setting for INT_CTL.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
 drivers/video/exynos/exynos_dp_reg.c |    2 +-
 drivers/video/exynos/exynos_dp_reg.h |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a..d67f49b 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
 void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
 {
 	/* Set interrupt pin assertion polarity as high */
-	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+	writel(INT_POL0 | INT_POL1, dp->reg_base + EXYNOS_DP_INT_CTL);
 
 	/* Clear pending regisers */
 	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014..8548b91 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
 
 /* EXYNOS_DP_INT_CTL */
 #define SOFT_INT_CTRL				(0x1 << 2)
-#define INT_POL					(0x1 << 0)
+#define INT_POL0				(0x1 << 0)
+#define INT_POL1				(0x1 << 1)
 
 /* EXYNOS_DP_SYS_CTL_1 */
 #define DET_STA					(0x1 << 2)
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH 12/12] OMAPDSS: DPI: always use DSI PLL if available
From: Tomi Valkeinen @ 2012-11-05  8:55 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob
In-Reply-To: <5093B4F3.1000703@ti.com>

[-- Attachment #1: Type: text/plain, Size: 3267 bytes --]

On 2012-11-02 13:56, Archit Taneja wrote:
> On Friday 02 November 2012 04:58 PM, Tomi Valkeinen wrote:
>> On 2012-11-02 13:09, Archit Taneja wrote:
>>> On Friday 02 November 2012 04:19 PM, Tomi Valkeinen wrote:
>>>> On 2012-11-02 12:44, Archit Taneja wrote:
>>>>
>>>>> Hmm, that makes sense. Anyway, I don't think it's really bad if we
>>>>> refer
>>>>> to dssdev->channel for now.
>>>>
>>>> It is, because dssdev->channel doesn't exist with DT.
>>>>
>>>> With DT we either need to figure out the channel in omapdss at runtime,
>>>> or add a property to the DT data telling the channel. And adding such a
>>>> property is not correct, as DT should be about describing the HW.
>>>
>>> Ok.
>>>
>>> I don't totally agree with your idea of figuring out the manager in
>>> panel the panel's probe. If it's done in the panel driver's probe
>>> itself, then by this point of time we have already set
>>> mgr->output->device links. If omapdss only does this stuff, then
>>
>> Hmm, I'm not sure I understand what's your point above? If figuring out
>> the mgr is done in panel's probe, the mgr->output link is not yet made
>> before that time.
> 
> My point is that we are trying to find a manager at panel's probe
> itself. It think that's what we do now. But one of your recent patch
> moves that to omapfb.

Ah. Yes, that's true.

>>> omapfb/omapdrm have just the job of connecting the overlays to the
>>> manager. Do you think that's okay?
>>
>> Yes, that's how I think it should be. I don't see why omapfb/omapdrm
>> should care about which manager is being used for the output, it doesn't
>> really matter as long there is one and it works.
>>
>> Then again, I don't have anything against omapfb/omapdrm choosing the
>> manager, but I don't see how they would have any better idea of which
>> manager to use than omapdss.
>>
>> But as doing the connections at probe time is a bit problematic, perhaps
>> we should have a new step in this whole sequence. Something like
>> "connect" or whatever, which would lock the required blocks in the whole
>> pipeline, and acquire the required resources that couldn't be gotten at
>> probe time.
>>
>> But even then, choosing the manager is not easy, as whoever chooses the
>> manager needs to observe all the possible displays used at the same
>> time...
> 
> Right. I was wondering if omapfb/omapdrm could understand the 'all
> possible displays information' better compared to a panel's probe.
> 
> Even omapdrm/omafb can't be perfect because we could insert a panel
> driver module at any time, and omapfb/omapdrm may miss that out.

True, omapdrm/fb may have a better idea. It's still unclear though.
Currently we have quite strict order in the sequence the modules need to
be loaded, which is quite bad and causes issues. We should make things
more dynamic, so that the initialization of the drivers could happen
more freely.

But that creates more problems: when booting up, omapfb starts. But
omapfb can't know if all the panel drivers have already been loaded.
omapfb may see that DVI is the default display, but what should it do if
DVI doesn't have a driver yet? It could wait, but perhaps the driver for
DVI will never even be loaded.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [PATCH v7 8/8] drm_modes: add of_videomode helpers
From: Thierry Reding @ 2012-11-05  9:10 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: devicetree-discuss, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Guennady Liakhovetski, linux-media,
	Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1351675689-26814-9-git-send-email-s.trumtrar@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 787 bytes --]

On Wed, Oct 31, 2012 at 10:28:08AM +0100, Steffen Trumtrar wrote:
[...]
> +/**
> + * 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
> + * 
> + * DESCRIPTION:

I don't think this is necessary.

> + * 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_timing_list ond

You probably meant "and" at the end of this line. Also I'm not even sure
that we should be exposing this function, but rather provide a helper
which automatically adds the parsed modes to a DRM connector object.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox