Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-20 Thread Russell King - ARM Linux
Another problem.

After performing several modesets, the IPU seems to lock up and produce
no syncs or output data.

I've seen this many times over the last week while testing out various
aspects of imx-drm, and had put it down to problems with the clocking
arrangement getting its settings wrong.  Now that I've sorted all that
though, and I still have the problem, there's something else going on.

What I see is:
- the HDMI clock is running correctly (right frequency and unmodulated)
- the TMDS data lines show signs of there being some data (probably
  control, guard bands and data islands from the frame composer in the
  HDMI interface).  The data lines are definitely lacking image data though.
- reading the various status registers indicates that all FIFOs within
  the IPU are empty.
- the attached TV says that there is no HDMI signal.

One of my tests has been to cycle through all display resolutions from the
smallest width to the largest, leaving each one set for 30 seconds.  This
will occasionally provoke the problem, but obviously is rather slow to do
so.

I tried this with a less demanding test last night as far as a change in
the settings: switching between 720p at 50 and 60Hz.  The clocks for these
two modes are the same at 74.25MHz, and the vertical timing parameters are
identical.  The only timing difference is with the horizontal parameters:

  1280x720 (0x41)   74.2MHz +HSync +VSync +preferred
h: width  1280 start 1390 end 1430 total 1650 skew0 clock   45.0KHz
v: height  720 start  725 end  730 total  750   clock   60.0Hz
  1280x720 (0x4f)   74.2MHz +HSync +VSync
h: width  1280 start 1720 end 1760 total 1980 skew0 clock   37.5KHz
v: height  720 start  725 end  730 total  750   clock   50.0Hz

This dies within a couple of minutes.  I haven't gathered enough
information to tell whether it always dies when switching from 50 - 60Hz
or whether it's any switch.

My test for this is basically:

while :; do
  xrandr -s 1280x720 -r 50
  sleep 5
  xrandr -s 1280x720 -r 60
  sleep 5
done
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-20 Thread Russell King - ARM Linux
On Sun, Oct 20, 2013 at 02:00:57PM +0100, Russell King - ARM Linux wrote:
 As for imx-drm, there was a warning which preceded that oops.  Here's the
 full log, below the - marker - this is from unbinding the imx-drm
 module, and then trying to reboot.
 
 imx-drm is really very broken in the way it tries to bend DRM to be
 used in DT - it doesn't consider the lifetime for anything like the
 CRTCs, connectors or encoders.  All these have empty .destroy functions
 to them. If we unbind imx-drm, the top level drm_device tries to be
 destroyed, but it leaves behind all the CRTCs, connectors and encoders,
 causing the first warning because none of the framebuffers got cleaned
 up through that destruction (because the functions did nothing.)
 
 The second one is through trying to clean up the framebuffer, which is
 still in use.
 
 The third one is caused because there's still allocated memory objects
 against the DRM memory manager - again, because nothing has been cleaned
 up.

Right, so how imx-drm works as far as DRM initialization is by a wing
and a prayer at the moment.

It works like this - the driver relies heavily upon this sequence:

- imx_drm_init()
  - creates an imx_drm_device structure to contain references to other
parts.
  - registers the imx-drm platform device and an associated structure.
- the platform device is immediately probed, causing it to be registered
  with the DRM subsystem.
- the DRM subsystem creates the drm_device structure, and calls the
  drivers -load method.
- the driver initialises some basic data, places a pointer to the
  drm_device into the imx_drm_device and returns
- imx_pd_driver_init()
  - registers the imx_pd_driver platform device driver for DT devices
with a compatible string of fsl,imx-parallel-display
  - such devices will be immediately probed
- these allocate an imx_parallel_display structure, which contains
  a drm_connector and drm_encoder structure embedded within.
- these structures are registered into the core of imx_drm, and
  via the imx_drm_device structure, are both attached to the
  drm_device immediately.
- imx_tve_driver_init()
  essentially the same as imx_pd_driver_init()
- imx_ldb_driver_init()
  essentially the same as imx_pd_driver_init()
- imx_ipu_driver_init()
  - registers a platform driver fot DT devices with a compatible string
of fsl,imx51-ipu, fsl,imx53-ipu, or fsl,imx6q-ipu.
  - initialises such devices, and creates two new platform devices
called imx-ipuv3-crtc, one for each display interface.
- ipu_drm_driver_init()
  - registers a platform driver for imx-ipuv3-crtc devices.
- for each device found
  - it allocates a ipu_crtc device structure, which embeds a drm_crtc
structure.
  - it registers a CRTC via imx_drm_add_crtc().
- this allocates an imx_drm_crtc structure, and eventually registers
  the drm_crtc structure against the drm_device
- imx_hdmi_driver_init
  similar to imx_pd_driver_init

All that sequence is in init level 6.  The last bit comes in init level 7
(the late_initcall):

- imx_fb_helper_init()
  - this grabs the drm_device, and calls drm_fbdev_cma_init() on it
hoping that we know the number of CRTCs at this point.  This is
held indefinitely.
  - the resulting drm_fbdev_cma is saved into the imx_drm_device.

Now, if the imx-drm device is unbound from its driver, all hell breaks
loose - none of these crtc/connector/encoder structures have a meaningful
destroy function - their destruction is all in their individual driver
remove functions.  This causes some warnings to be spat out from DRM.

Amongst this is the last_close callback which looks at the imx_drm_device,
sees that drm_fbdev_cma is registered against it, and calls
drm_fbdev_cma_restore_mode() on it.  drm_fbdev_cma contains objects which
store a pointer to the drm_device structure that it was registered against,
which exists at this point, so everything is fine.

The unload proceeds, and eventually the drm_device is freed.

Now, if we rebind the imx-drm device, causing the probe actions above to
be repeated.  imx_drm_device still contains a pointer to the drm_fbdev_cma
object that was allocated...  Let's ignore the fact that none of the
sub-modules have re-initialised anything against this new drm_device.

The real fun comes when you try and unbind it again.  This time, the
drm_device which is being torn down isn't the one in drm_fbdev_cma,
but we still call drm_fbdev_cma_restore_mode().  This tries to get a
mutex on the _original_ drm_device-mode_config.mutex, which has been
freed.  The result is a kernel oops.

Now, several things stand out here: piece-meal construction of a
drm_device in this manner is unsafe:
- it relies heavily on all devices already being present at the time that
  the above sequence starts, and it assumes that the drivers will probe
  immediately, as soon as they are registered.
- the late_initcall() is really a barrier on the 

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-20 Thread Russell King - ARM Linux
On Sun, Oct 20, 2013 at 05:31:56PM +0100, Russell King - ARM Linux wrote:
 On Sun, Oct 20, 2013 at 02:00:57PM +0100, Russell King - ARM Linux wrote:
  As for imx-drm, there was a warning which preceded that oops.  Here's the
  full log, below the - marker - this is from unbinding the imx-drm
  module, and then trying to reboot.
  
  imx-drm is really very broken in the way it tries to bend DRM to be
  used in DT - it doesn't consider the lifetime for anything like the
  CRTCs, connectors or encoders.  All these have empty .destroy functions
  to them. If we unbind imx-drm, the top level drm_device tries to be
  destroyed, but it leaves behind all the CRTCs, connectors and encoders,
  causing the first warning because none of the framebuffers got cleaned
  up through that destruction (because the functions did nothing.)
  
  The second one is through trying to clean up the framebuffer, which is
  still in use.
  
  The third one is caused because there's still allocated memory objects
  against the DRM memory manager - again, because nothing has been cleaned
  up.
 
 Right, so how imx-drm works as far as DRM initialization is by a wing
 and a prayer at the moment.
 
 It works like this - the driver relies heavily upon this sequence:
 
 - imx_drm_init()
   - creates an imx_drm_device structure to contain references to other
 parts.
   - registers the imx-drm platform device and an associated structure.
 - the platform device is immediately probed, causing it to be registered
   with the DRM subsystem.
 - the DRM subsystem creates the drm_device structure, and calls the
   drivers -load method.
 - the driver initialises some basic data, places a pointer to the
   drm_device into the imx_drm_device and returns
 - imx_pd_driver_init()
   - registers the imx_pd_driver platform device driver for DT devices
 with a compatible string of fsl,imx-parallel-display
   - such devices will be immediately probed
 - these allocate an imx_parallel_display structure, which contains
   a drm_connector and drm_encoder structure embedded within.
 - these structures are registered into the core of imx_drm, and
   via the imx_drm_device structure, are both attached to the
   drm_device immediately.
 - imx_tve_driver_init()
   essentially the same as imx_pd_driver_init()
 - imx_ldb_driver_init()
   essentially the same as imx_pd_driver_init()
 - imx_ipu_driver_init()
   - registers a platform driver fot DT devices with a compatible string
 of fsl,imx51-ipu, fsl,imx53-ipu, or fsl,imx6q-ipu.
   - initialises such devices, and creates two new platform devices
 called imx-ipuv3-crtc, one for each display interface.
 - ipu_drm_driver_init()
   - registers a platform driver for imx-ipuv3-crtc devices.
 - for each device found
   - it allocates a ipu_crtc device structure, which embeds a drm_crtc
 structure.
   - it registers a CRTC via imx_drm_add_crtc().
 - this allocates an imx_drm_crtc structure, and eventually registers
   the drm_crtc structure against the drm_device
 - imx_hdmi_driver_init
   similar to imx_pd_driver_init
 
 All that sequence is in init level 6.  The last bit comes in init level 7
 (the late_initcall):
 
 - imx_fb_helper_init()
   - this grabs the drm_device, and calls drm_fbdev_cma_init() on it
 hoping that we know the number of CRTCs at this point.  This is
 held indefinitely.
   - the resulting drm_fbdev_cma is saved into the imx_drm_device.
 
 Now, if the imx-drm device is unbound from its driver, all hell breaks
 loose - none of these crtc/connector/encoder structures have a meaningful
 destroy function - their destruction is all in their individual driver
 remove functions.  This causes some warnings to be spat out from DRM.
 
 Amongst this is the last_close callback which looks at the imx_drm_device,
 sees that drm_fbdev_cma is registered against it, and calls
 drm_fbdev_cma_restore_mode() on it.  drm_fbdev_cma contains objects which
 store a pointer to the drm_device structure that it was registered against,
 which exists at this point, so everything is fine.
 
 The unload proceeds, and eventually the drm_device is freed.
 
 Now, if we rebind the imx-drm device, causing the probe actions above to
 be repeated.  imx_drm_device still contains a pointer to the drm_fbdev_cma
 object that was allocated...  Let's ignore the fact that none of the
 sub-modules have re-initialised anything against this new drm_device.
 
 The real fun comes when you try and unbind it again.  This time, the
 drm_device which is being torn down isn't the one in drm_fbdev_cma,
 but we still call drm_fbdev_cma_restore_mode().  This tries to get a
 mutex on the _original_ drm_device-mode_config.mutex, which has been
 freed.  The result is a kernel oops.
 
 Now, several things stand out here: piece-meal construction of a
 drm_device in this manner is unsafe:
 - it relies heavily on all devices already being present at the time 

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-19 Thread Russell King - ARM Linux
On Wed, Oct 16, 2013 at 11:31:07AM -0700, Greg Kroah-Hartman wrote:
 On Wed, Oct 16, 2013 at 07:07:35PM +0100, Russell King - ARM Linux wrote:
  Sorry, but I don't think imx-drm is driving the hardware correctly, and
  I know that Greg wants it moved out of drivers/staging, but frankly it
  seems to be far from ready for that.  Certainly the HDMI parts seems to
  be especially problematical.
 
 I want it out of staging if it's working properly.  Yours is the first
 report of it not working properly, and in fact, probably one of the
 first users of the driver, as I haven't gotten any reports of it working
 or not at all over the years.

Next problem... unbinding, rebinding, and then unbinding the imx-drm
device produces the nice oops below.  I've not debugged this yet.

Alignment trap: not handling instruction e1932f9f at [c00758ec]
Unhandled fault: alignment exception (0x001) at 0x6e72666f
Internal error: : 1 [#1] SMP ARM
Modules linked in: fuse bnep rfcomm bluetooth
CPU: 0 PID: 1125 Comm: bash Tainted: GW3.12.0-rc4+ #123
task: d0d6ec00 ti: d7ff2000 task.ti: d7ff2000
PC is at __lock_acquire+0x1a8/0x1e14
LR is at lock_acquire+0x68/0x7c
pc : [c00758f0]lr : [c0077aa8]psr: 20070093
sp : d7ff3cc8  ip :   fp : d7ff3d54
r10: db2a6334  r9 :   r8 : 6e72656b
r7 : c0846208  r6 : c08852cc  r5 : d0d6ec00  r4 : 0002
r3 : 6e72666f  r2 : db2a6334  r1 : 0001  r0 : d7ff2000
Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c53c7d  Table: 20df804a  DAC: 0015
Process bash (pid: 1125, stack limit = 0xd7ff2240)
Stack: (0xd7ff3cc8 to 0xd7ff4000)
3cc0:   0006 0007 c0cd22f0 0006 d7ff3d1c d7ff3ce8
3ce0: c00782f8 c0075050 0001  db801f00 d7ff2000 c0078648 d7ff2000
3d00: 0001 d7ff3e08 d7ff3e60 d7ff3dd8 d7ff3d3c d7ff3d20  d7ff3e08
3d20: d7ff3d7c d7ff3d30 c0072a58  d7ff2000 60070013 d0d6ec00 d7ff2000
3d40: c06679c8 d0d6ec00 d7ff3d8c d7ff3d58 c0077aa8 c0075754 0002 
3d60:  c02ff27c  0002 db2a62fc c02ff27c c08852cc 
3d80: d7ff3de4 d7ff3d90 c05f80c4 c0077a4c 0002  c02ff27c c0072a20
3da0: dad64000 d7ff3e24 d7ff3df8 d7ff3e04 d7ff3e5c d0d6f000 c013f1c8 db322880
3dc0: db2a6440 db2a6000 c0872568 0008 c06679c8 db286000 d7ff3e04 d7ff3de8
3de0: c02ff27c c05f8074 db280f00 db322880 db2a6000 db29b810 d7ff3e1c d7ff3e08
3e00: c02f13ac c02ff268 d0e55000 c087265c d7ff3e2c d7ff3e20 c0464d7c c02f1398
3e20: d7ff3e54 d7ff3e30 c02f506c c0464d68 d0e55000 c087265c db29b810 c0872568
3e40: 0008 db286000 d7ff3e74 d7ff3e58 c02fa284 c02f503c c087265c c087265c
3e60: db29b810 0008 d7ff3e8c d7ff3e78 c02fb900 c02fa258 db29b810 c0872678
3e80: d7ff3e9c d7ff3e90 c0464d54 c02fb8d4 d7ff3eac d7ff3ea0 c0312bfc c0464d44
3ea0: d7ff3ec4 d7ff3eb0 c03113b0 c0312be8 db29b844 db29b810 d7ff3edc d7ff3ec8
3ec0: c0311434 c0311344 c0872678 c085b588 d7ff3efc d7ff3ee0 c03103ac c0311418
3ee0: c941b300 c941b318 d7ff3f70 db28c280 d7ff3f0c d7ff3f00 c030f934 c0310338
3f00: d7ff3f3c d7ff3f10 c013d7d0 c030f918 d7ff3f70 dbb5e600 0008 003ba408
3f20: d7ff3f70   0008 d7ff3f6c d7ff3f40 c00db77c c013d6d4
3f40: 0001 c000eb44 dbb5e600  d7ff3f70 003ba408  0008
3f60: d7ff3fa4 d7ff3f70 c00dbb58 c00db6b8   d7ff3f94 b6f7fa78
3f80: 0008 003ba408 0004 c000eb44 d7ff2000   d7ff3fa8
3fa0: c000e980 c00dbb18 b6f7fa78 0008 0001 003ba408 0008 
3fc0: b6f7fa78 0008 003ba408 0004 bee5c9ec 000a6094  003f7f08
3fe0:  bee5c96c b6eee747 b6f2611c 40070010 0001 0138 0020
Backtrace: 
[c0075748] (__lock_acquire+0x0/0x1e14) from [c0077aa8] 
(lock_acquire+0x68/0x7c)
[c0077a40] (lock_acquire+0x0/0x7c) from [c05f80c4] 
(mutex_lock_nested+0x5c/0x394)
 r7: r6:c08852cc r5:c02ff27c r4:db2a62fc
[c05f8068] (mutex_lock_nested+0x0/0x394) from [c02ff27c] 
(drm_modeset_lock_all+0x20/0x58)
[c02ff25c] (drm_modeset_lock_all+0x0/0x58) from [c02f13ac] 
(drm_fbdev_cma_restore_mode+0x20/0x34)
 r6:db29b810 r5:db2a6000 r4:db322880 r3:db280f00
[c02f138c] (drm_fbdev_cma_restore_mode+0x0/0x34) from [c0464d7c] 
(imx_drm_driver_lastclose+0x20/0x24)
 r5:c087265c r4:d0e55000
[c0464d5c] (imx_drm_driver_lastclose+0x0/0x24) from [c02f506c] 
(drm_lastclose+0x3c/0x174)
[c02f5030] (drm_lastclose+0x0/0x174) from [c02fa284] 
(drm_put_dev+0x38/0x154)
[c02fa24c] (drm_put_dev+0x0/0x154) from [c02fb900] 
(drm_platform_exit+0x38/0x5c)
 r7:0008 r6:db29b810 r5:c087265c r4:c087265c
[c02fb8c8] (drm_platform_exit+0x0/0x5c) from [c0464d54] 
(imx_drm_platform_remove+0x1c/0x24)
 r5:c0872678 r4:db29b810
[c0464d38] (imx_drm_platform_remove+0x0/0x24) from [c0312bfc] 
(platform_drv_remove+0x20/0x24)
[c0312bdc] (platform_drv_remove+0x0/0x24) from [c03113b0] 
(__device_release_driver+0x78/0xd4)
[c0311338] (__device_release_driver+0x0/0xd4) from [c0311434] 
(device_release_driver+0x28/0x34)
 r5:db29b810 r4:db29b844
[c031140c] 

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-17 Thread Lucas Stach
Hi Russell,

Am Mittwoch, den 16.10.2013, 20:02 +0100 schrieb Russell King - ARM
Linux:
 On Wed, Oct 16, 2013 at 11:31:07AM -0700, Greg Kroah-Hartman wrote:
  On Wed, Oct 16, 2013 at 07:07:35PM +0100, Russell King - ARM Linux wrote:
   Sorry, but I don't think imx-drm is driving the hardware correctly, and
   I know that Greg wants it moved out of drivers/staging, but frankly it
   seems to be far from ready for that.  Certainly the HDMI parts seems to
   be especially problematical.
  
  I want it out of staging if it's working properly.  Yours is the first
  report of it not working properly, and in fact, probably one of the
  first users of the driver, as I haven't gotten any reports of it working
  or not at all over the years.
 
 Well, part of that is because I have this other thing called Armada DRM,
 which is a similar thing to imx-drm, except for the Marvell Dove SoCs,
 so it's been really quite easy to get a full Ubuntu 12.04 up and running
 on the IMX SoC I have here.
 
 As part of that effort, I'm now using my Armada DRM Xorg driver with
 imx-drm to test this stuff out.  (Bearing in mind that IMX and Dove use
 the same Vivante GPU, there's some sense in getting my Xorg Armada DRM
 driver working on both.)
 
 I'm not aware of there being any X drivers for imx-drm (google turns
 up nothing), which might be a reason why it hasn't been well tested
 and has also languished in drivers/staging for soo long.  Alternatively,
 maybe my google searching sucks, or it is out there somewhere but
 hidden from googlebot?
 

X.Org isn't the center of the world anymore. For some general purpose
distros this might still hold true for some time, but certainly not for
the use-cases we test this driver with.

For most of our embedded use-cases we currently use the FBdev emulation
(phasing this out at the moment) or the apps are sitting right on top of
the raw KMS APIs, rather than on top of a display server.
We also did some experiments with Wayland (Weston) on top of imx-drm,
which worked quite well.

There might be dragons hiding in some corners for the more general
purpose use-cases and we are happy to have you test the driver and
provide valuable reports.

 To be fair, so far most of the problems I'm finding are with the HDMI
 addition to imx-drm rather than imx-drm itself: there's been the lockdep
 problem and the clock polarity problem which the HDMI stuff discovered.
 
 Looking at the todo list for moving it out of staging, we have:
 
 - get DRM Maintainer review for this code
 - Wait for common display framework to hit mainline and update the IPU
   driver to use it. This will most probably make changes to the devicetree
   bindings necessary.
 - Factor out more code to common helper functions
 - decide where to put the base driver. It is not specific to a subsystem
   and would be used by DRM/KMS and media/V4L2
 
 (1) is quite a difficult task: I'm waiting for a review of the Armada DRM
 stuff, which I'm hoping will make the next merge window.  Rob Clark is
 looking at that but has been distracted recently from completing it.
 
 (2) CDF... has been around in RFC according to LWN.net but doesn't seem to
 make much in the way of progress from what I can see, despite there
 allegedly being many developers show[ing] interest in the first RFC.
 CDF is over a year old now - first RFC 17 Aug 2012, second 22 Nov 2012,
 third 9 Aug 2013.
 

Philipp has a prototype of CDF on imx-drm working internally and I
suspect he will be able to post patches shortly after ELCE.

 (3) is an on-going effort and really isn't a reason for it to stay in
 staging.
 
 (4) is probably the biggest issue.  The problem there is that the IMX
 display subsystem is very flexible: it's basically a set of DMA engines
 on the front, and behind that a fair number of modules implementing
 facilities like image rotation, display driving and image capture.
 Display driving alone involves setting up waveforms and writing some
 microcode to tell the thing what to do on certain events (like end
 of frame etc.)  Hence it doesn't fit well into any particular Linux
 subsystem.  In this regard, it's a victim of its own flexibility.

We are aiming to do the same thing as the Tegra host1x driver: move the
IPU core to drivers/gpu and export API for other drivers to use. This
may mean we still have to keep the DRM part in staging (at least until
the CDF thing is sorted, as this prevents us from setting the devicetree
bindings in stone), but at least should be a step in the right
direction.

Regards,
Lucas

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

___
devel mailing list
de...@linuxdriverproject.org

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-17 Thread Russell King - ARM Linux
Okay, next problem...

As I described via the Cubox-i community last night on google+...

I'm now at the point where certain resolutions and refreshes work fine
(eg, 720p @ 50 or 60Hz, 1366x768, 1024x768).

Others either don't display (1080p, 800x600, 848x480, 640x480), or have
speckles, a line of corruption that flashes up, and blanks (576p @50 Hz,
480p @60Hz), possibly a result of loss of signal.

I've been looking at the DMFC, suspecting a fifo problem, but that to me
looks fine - we seem to always allocate 4 slots, with each slot having a
bandwidth of 99Mpixels each.  This in theory should give a maximum of
396Mpixels, which is more than plenty.  The bandwidth calculation is
probably wrong though - the peak bandwidth is actually the pixel clock
since this is the rate at which pixels have to be supplied during a line,
not the refresh * hdisplayed * vdisplayed - that's the average bandwidth
over a full frame.

However, if it was a DMFC problem, and as this only carries pixel data,
I'd expect that not to cause loss of signal.

I've checked the phy MPLL settings back to the manual for certain problem
clock rates, and they also seem fine.  I've polled the status register to
see whether it's unstable, and it appears to remain locked.

I think I should probe the HDMI signals, particularly the clock signal to
see if that provides any useful clues.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-16 Thread Russell King - ARM Linux
On Tue, Oct 15, 2013 at 10:17:07AM -0300, Fabio Estevam wrote:
 On Tue, Oct 15, 2013 at 10:10 AM, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
  Another point on patch 1.  Sorry, I don't have patch 1 to reply to, it
  seems it was deleted from linux-arm-kernel's moderation queue.
 
  drm_mode_connector_attach_encoder() is called too early, before the
  base.id field in the encoder has been initialised.  This causes the
  connectors encoder array to be empty, and userspace KMS to fail.
 
  There's also bugs in the CSC setting too - it runs off the end of the
  array and gcc warns about this.  The code was clearly wrong.
 
  You may wish to combine this patch with patch 1 to sort all that out.
  For the patch below:
 
  Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
  Tested-by: Russell King rmk+ker...@arm.linux.org.uk
 
 Thanks, Russell.
 
 Will submit v3 when I am back to the office.

Okay, I still have a problem with HDMI: I have a magenta vertical line
down the left hand side of the frame, the displayed frame is shifted
right by the width of that line and the right hand side is missing some
pixels.

First off, the hsync position programmed into the HDMI registers appears
to be wrong.

I'm at a loss why imx-hdmi is obfuscated with a conversion from a
drm_display_mode structure to a fb_videomode.  This adds additional
confusion and additional opportunities for bugs; this is probably
exactly why the hsync position is wrong.

In CEA-861-B for 720p @60Hz:

DE: __^^^
HS: ___^^^___
 ^  ^  ^
 |  |  220 clocks
 |  40 clocks
 110 clocks

The IMX6 manual says HSYINCINDELAY0 is Hsync active edge delay.  Integer
number of pixel clock cycles from de non-active edge.  So, this should be
110.  Yet it ends up being programmed as 220, leading to a magenta vertical
bar down the left hand side of the display.

Now, if you look at Documentation/fb/framebuffer.txt, in this case, the
right margin should be 110 clocks, hsync len should be 40 and the left
margin should be 220 clocks.

However, this is not what your conversion to a fb_videomode does.  It
reverses the left and right margin.  A similar confusion also exists
in the conversion of the upper/lower margins too.

The DRM model is this (for 720p @60Hz):

0 1280 1390 1430  1650
|===||---|--|
^   ^^   ^  ^
start   hdisplay hsync_start hsync_end htotal

The fb model is the same as the above but rotated:

left margindisplayedright margin hsync_len
|--|===||---|

So, the left margin is the bit between hsync_end and htotal, and the
right margin is the bit between hdisplay and hsync_start.  Exactly
the same analysis applies to the upper/lower margins.

What I suggest is that the use of fb_videomode is entirely killed off
in this driver to remove this layer of confusion and instead the DRM
model is stuck to within this DRM driver.

Now on to the next problem.  HSYNC/VSYNC polarity.

So, this is the mode which is set:

  1280x720 (0x41)   74.2MHz +HSync +VSync *current +preferred
h: width  1280 start 1390 end 1430 total 1650 skew0 clock   45.0KHz
v: height  720 start  725 end  730 total  750   clock   60.0Hz

Note the positive HSync and VSync polarity - this is correct, backed
up by CEA-861-B.

The IPU DI0 is configured thusly in its general control register:
0x264 = 0x26, which is what is set when the requested mode
has DRM_MODE_FLAG_PHSYNC and DRM_MODE_FLAG_PVSYNC flags set.

However, if we look at the HDMI config: 0x121000 = 0x18.  Active low
hsync/vsync.  This is quite obvious when you look at the code -
convert_to_video_timing() does *nothing* at all when converting the
sync polarities, which means hdmi_av_composer() doesn't program them
appropriately.  And yes, poking 0x78 into this register finally fixes
the problem.

Yet another reason why this silly conversion from one structure form
to another is a Very Bad Idea.  Until I found this, I was merely going
to send a patch to sort out convert_to_video_timing(), but quite frankly
I'm going to kill this thing off right now.

Another thing:

static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
{
int ret;
convert_to_video_timing(hdmi-fb_mode, mode);

hdmi_disable_overflow_interrupts(hdmi);

hdmi-vic = 6;

It's quite wrong to force every video mode set to be CEA mode 6.  IIRC,
There is a function in DRM which will tell you the CEA mode number.
Again, I'll fix this in my patch rewriting this bit of the driver to
be correct.

I'm also suspicious of the HDMI Initialization Step comments, because
they make no sense:

/* HDMI Initialization Step B.4 */
static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
{

yet:


Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-16 Thread Russell King - ARM Linux
On Wed, Oct 16, 2013 at 12:37:42PM -0700, Troy Kisky wrote:
 On 10/16/2013 10:03 AM, Russell King - ARM Linux wrote:
 On Tue, Oct 15, 2013 at 10:17:07AM -0300, Fabio Estevam wrote:
 On Tue, Oct 15, 2013 at 10:10 AM, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
 Another point on patch 1.  Sorry, I don't have patch 1 to reply to, it
 seems it was deleted from linux-arm-kernel's moderation queue.

 drm_mode_connector_attach_encoder() is called too early, before the
 base.id field in the encoder has been initialised.  This causes the
 connectors encoder array to be empty, and userspace KMS to fail.

 There's also bugs in the CSC setting too - it runs off the end of the
 array and gcc warns about this.  The code was clearly wrong.

 You may wish to combine this patch with patch 1 to sort all that out.
 For the patch below:

 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 Tested-by: Russell King rmk+ker...@arm.linux.org.uk
 Thanks, Russell.

 Will submit v3 when I am back to the office.
 Okay, I still have a problem with HDMI: I have a magenta vertical line
 down the left hand side of the frame, the displayed frame is shifted
 right by the width of that line and the right hand side is missing some
 pixels.

 First off, the hsync position programmed into the HDMI registers appears
 to be wrong.

 I'm at a loss why imx-hdmi is obfuscated with a conversion from a
 drm_display_mode structure to a fb_videomode.  This adds additional
 confusion and additional opportunities for bugs; this is probably
 exactly why the hsync position is wrong.

 In CEA-861-B for 720p @60Hz:

 DE: __^^^
 HS: ___^^^___
   ^  ^  ^
   |  |  220 clocks
   |  40 clocks
   110 clocks

 The IMX6 manual says HSYINCINDELAY0 is Hsync active edge delay.  Integer
 number of pixel clock cycles from de non-active edge.  So, this should be
 110.  Yet it ends up being programmed as 220, leading to a magenta vertical
 bar down the left hand side of the display.

 Now, if you look at Documentation/fb/framebuffer.txt, in this case, the
 right margin should be 110 clocks, hsync len should be 40 and the left
 margin should be 220 clocks.

 However, this is not what your conversion to a fb_videomode does.  It
 reverses the left and right margin.  A similar confusion also exists
 in the conversion of the upper/lower margins too.

 The DRM model is this (for 720p @60Hz):

 0 1280 1390 1430  1650
 |===||---|--|
 ^   ^^   ^  ^
 start   hdisplay hsync_start hsync_end htotal

 The fb model is the same as the above but rotated:

 left margindisplayedright margin hsync_len
 |--|===||---|

 So, the left margin is the bit between hsync_end and htotal, and the
 right margin is the bit between hdisplay and hsync_start.  Exactly
 the same analysis applies to the upper/lower margins.

 What I suggest is that the use of fb_videomode is entirely killed off
 in this driver to remove this layer of confusion and instead the DRM
 model is stuck to within this DRM driver.

 Now on to the next problem.  HSYNC/VSYNC polarity.

 So, this is the mode which is set:

1280x720 (0x41)   74.2MHz +HSync +VSync *current +preferred
  h: width  1280 start 1390 end 1430 total 1650 skew0 clock   
 45.0KHz
  v: height  720 start  725 end  730 total  750   clock   
 60.0Hz

 Note the positive HSync and VSync polarity - this is correct, backed
 up by CEA-861-B.

 The IPU DI0 is configured thusly in its general control register:
 0x264 = 0x26, which is what is set when the requested mode
 has DRM_MODE_FLAG_PHSYNC and DRM_MODE_FLAG_PVSYNC flags set.

 However, if we look at the HDMI config: 0x121000 = 0x18.  Active low
 hsync/vsync.  This is quite obvious when you look at the code -
 convert_to_video_timing() does *nothing* at all when converting the
 sync polarities, which means hdmi_av_composer() doesn't program them
 appropriately.  And yes, poking 0x78 into this register finally fixes
 the problem.

 Yet another reason why this silly conversion from one structure form
 to another is a Very Bad Idea.  Until I found this, I was merely going
 to send a patch to sort out convert_to_video_timing(), but quite frankly
 I'm going to kill this thing off right now.

 Another thing:

 static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode 
 *mode)
 {
  int ret;
  convert_to_video_timing(hdmi-fb_mode, mode);

  hdmi_disable_overflow_interrupts(hdmi);
   hdmi-vic = 6;

 It's quite wrong to force every video mode set to be CEA mode 6.  IIRC,
 There is a function in DRM which will tell you the CEA mode number.
 Again, I'll fix this in my patch rewriting this bit of the driver to
 be correct.

 I'm also 

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-16 Thread Troy Kisky

On 10/16/2013 1:27 PM, Russell King - ARM Linux wrote:

On Wed, Oct 16, 2013 at 12:37:42PM -0700, Troy Kisky wrote:

On 10/16/2013 10:03 AM, Russell King - ARM Linux wrote:

On Tue, Oct 15, 2013 at 10:17:07AM -0300, Fabio Estevam wrote:

On Tue, Oct 15, 2013 at 10:10 AM, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:

Another point on patch 1.  Sorry, I don't have patch 1 to reply to, it
seems it was deleted from linux-arm-kernel's moderation queue.

drm_mode_connector_attach_encoder() is called too early, before the
base.id field in the encoder has been initialised.  This causes the
connectors encoder array to be empty, and userspace KMS to fail.

There's also bugs in the CSC setting too - it runs off the end of the
array and gcc warns about this.  The code was clearly wrong.

You may wish to combine this patch with patch 1 to sort all that out.
For the patch below:

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
Tested-by: Russell King rmk+ker...@arm.linux.org.uk

Thanks, Russell.

Will submit v3 when I am back to the office.

Okay, I still have a problem with HDMI: I have a magenta vertical line
down the left hand side of the frame, the displayed frame is shifted
right by the width of that line and the right hand side is missing some
pixels.

First off, the hsync position programmed into the HDMI registers appears
to be wrong.

I'm at a loss why imx-hdmi is obfuscated with a conversion from a
drm_display_mode structure to a fb_videomode.  This adds additional
confusion and additional opportunities for bugs; this is probably
exactly why the hsync position is wrong.

In CEA-861-B for 720p @60Hz:

DE: __^^^
HS: ___^^^___
   ^  ^  ^
   |  |  220 clocks
   |  40 clocks
   110 clocks

The IMX6 manual says HSYINCINDELAY0 is Hsync active edge delay.  Integer
number of pixel clock cycles from de non-active edge.  So, this should be
110.  Yet it ends up being programmed as 220, leading to a magenta vertical
bar down the left hand side of the display.

Now, if you look at Documentation/fb/framebuffer.txt, in this case, the
right margin should be 110 clocks, hsync len should be 40 and the left
margin should be 220 clocks.

However, this is not what your conversion to a fb_videomode does.  It
reverses the left and right margin.  A similar confusion also exists
in the conversion of the upper/lower margins too.

The DRM model is this (for 720p @60Hz):

0 1280 1390 1430  1650
|===||---|--|
^   ^^   ^  ^
start   hdisplay hsync_start hsync_end htotal

The fb model is the same as the above but rotated:

left margindisplayedright margin hsync_len
|--|===||---|

So, the left margin is the bit between hsync_end and htotal, and the
right margin is the bit between hdisplay and hsync_start.  Exactly
the same analysis applies to the upper/lower margins.

What I suggest is that the use of fb_videomode is entirely killed off
in this driver to remove this layer of confusion and instead the DRM
model is stuck to within this DRM driver.

Now on to the next problem.  HSYNC/VSYNC polarity.

So, this is the mode which is set:

1280x720 (0x41)   74.2MHz +HSync +VSync *current +preferred
  h: width  1280 start 1390 end 1430 total 1650 skew0 clock   
45.0KHz
  v: height  720 start  725 end  730 total  750   clock   60.0Hz

Note the positive HSync and VSync polarity - this is correct, backed
up by CEA-861-B.

The IPU DI0 is configured thusly in its general control register:
0x264 = 0x26, which is what is set when the requested mode
has DRM_MODE_FLAG_PHSYNC and DRM_MODE_FLAG_PVSYNC flags set.

However, if we look at the HDMI config: 0x121000 = 0x18.  Active low
hsync/vsync.  This is quite obvious when you look at the code -
convert_to_video_timing() does *nothing* at all when converting the
sync polarities, which means hdmi_av_composer() doesn't program them
appropriately.  And yes, poking 0x78 into this register finally fixes
the problem.

Yet another reason why this silly conversion from one structure form
to another is a Very Bad Idea.  Until I found this, I was merely going
to send a patch to sort out convert_to_video_timing(), but quite frankly
I'm going to kill this thing off right now.

Another thing:

static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
{
  int ret;
  convert_to_video_timing(hdmi-fb_mode, mode);

  hdmi_disable_overflow_interrupts(hdmi);
   hdmi-vic = 6;

It's quite wrong to force every video mode set to be CEA mode 6.  IIRC,
There is a function in DRM which will tell you the CEA mode number.
Again, I'll fix this in my patch rewriting this bit of the driver to
be correct.

I'm also suspicious of the HDMI 

Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-16 Thread Russell King - ARM Linux
On Wed, Oct 16, 2013 at 02:03:17PM -0700, Troy Kisky wrote:
 Freescale's kernel(imx_3.0.35_4.1.0) has this code

 video/mxc_hdmi.c-/* Workaround to clear the overflow condition */
 video/mxc_hdmi.c-static void mxc_hdmi_clear_overflow(void)
 video/mxc_hdmi.c-{
 video/mxc_hdmi.c-   int count;
 video/mxc_hdmi.c-   u8 val;
 video/mxc_hdmi.c-
 video/mxc_hdmi.c-   /* TMDS software reset */
 video/mxc_hdmi.c: hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,  
 HDMI_MC_SWRSTZ);
 video/mxc_hdmi.c-
 video/mxc_hdmi.c-   val = hdmi_readb(HDMI_FC_INVIDCONF);
 video/mxc_hdmi.c-
 video/mxc_hdmi.c-   if (cpu_is_mx6dl()) {
 video/mxc_hdmi.c-hdmi_writeb(val, HDMI_FC_INVIDCONF);
 video/mxc_hdmi.c-return;
 video/mxc_hdmi.c-   }
 video/mxc_hdmi.c-
 video/mxc_hdmi.c-   for (count = 0 ; count  5 ; count++)
 video/mxc_hdmi.c-   hdmi_writeb(val, HDMI_FC_INVIDCONF);
 video/mxc_hdmi.c-}

 So, perhaps you need to move the software reset first.

Just tried that - and yes, it does work (I'm on i.MX 6Solo for which
cpu_is_mx6dl() would return true.)  Well done!

Indeed yes, the workaround in the code Fabio has differs from the
procedure given in the errata.

Note that this gives a new problem: we shouldn't use cpu_is_mx6dl()
in drivers - differences like this should be specified via DT properties.
I think we need this to recognise both fsl,imx6q-hdmi and fsl,imx6dl-hdmi
so that this workaround can detect when its running on a Solo/DL SoC.

Well, I now have quite a pile of patches for the hdmi code. :(
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-15 Thread Russell King - ARM Linux
Another point on patch 1.  Sorry, I don't have patch 1 to reply to, it
seems it was deleted from linux-arm-kernel's moderation queue.

drm_mode_connector_attach_encoder() is called too early, before the
base.id field in the encoder has been initialised.  This causes the
connectors encoder array to be empty, and userspace KMS to fail.

There's also bugs in the CSC setting too - it runs off the end of the
array and gcc warns about this.  The code was clearly wrong.

You may wish to combine this patch with patch 1 to sort all that out.
For the patch below:

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
Tested-by: Russell King rmk+ker...@arm.linux.org.uk

diff --git a/drivers/staging/imx-drm/imx-hdmi.c 
b/drivers/staging/imx-drm/imx-hdmi.c
index e227eb1..ca0450b 100644
--- a/drivers/staging/imx-drm/imx-hdmi.c
+++ b/drivers/staging/imx-drm/imx-hdmi.c
@@ -507,7 +507,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi 
*hdmi)
hdmi_writeb(hdmi, ((*csc_coeff)[0][2]  0xff), HDMI_CSC_COEF_A3_LSB);
hdmi_writeb(hdmi, ((*csc_coeff)[0][2]  8), HDMI_CSC_COEF_A3_MSB);
hdmi_writeb(hdmi, ((*csc_coeff)[0][3]  0xff), HDMI_CSC_COEF_A4_LSB);
-   hdmi_writeb(hdmi, ((*csc_coeff)[0][4]  8), HDMI_CSC_COEF_A4_MSB);
+   hdmi_writeb(hdmi, ((*csc_coeff)[0][3]  8), HDMI_CSC_COEF_A4_MSB);
 
hdmi_writeb(hdmi, ((*csc_coeff)[1][0]  0xff), HDMI_CSC_COEF_B1_LSB);
hdmi_writeb(hdmi, ((*csc_coeff)[1][0]  8), HDMI_CSC_COEF_B1_MSB);
@@ -516,7 +516,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi 
*hdmi)
hdmi_writeb(hdmi, ((*csc_coeff)[1][2]  0xff), HDMI_CSC_COEF_B3_LSB);
hdmi_writeb(hdmi, ((*csc_coeff)[1][2]  8), HDMI_CSC_COEF_B3_MSB);
hdmi_writeb(hdmi, ((*csc_coeff)[1][3]  0xff), HDMI_CSC_COEF_B4_LSB);
-   hdmi_writeb(hdmi, ((*csc_coeff)[1][4]  8), HDMI_CSC_COEF_B4_MSB);
+   hdmi_writeb(hdmi, ((*csc_coeff)[1][3]  8), HDMI_CSC_COEF_B4_MSB);
 
hdmi_writeb(hdmi, ((*csc_coeff)[2][0]  0xff), HDMI_CSC_COEF_C1_LSB);
hdmi_writeb(hdmi, ((*csc_coeff)[2][0]  8), HDMI_CSC_COEF_C1_MSB);
@@ -525,7 +525,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi 
*hdmi)
hdmi_writeb(hdmi, ((*csc_coeff)[2][2]  0xff), HDMI_CSC_COEF_C3_LSB);
hdmi_writeb(hdmi, ((*csc_coeff)[2][2]  8), HDMI_CSC_COEF_C3_MSB);
hdmi_writeb(hdmi, ((*csc_coeff)[2][3]  0xff), HDMI_CSC_COEF_C4_LSB);
-   hdmi_writeb(hdmi, ((*csc_coeff)[2][4]  8), HDMI_CSC_COEF_C4_MSB);
+   hdmi_writeb(hdmi, ((*csc_coeff)[2][3]  8), HDMI_CSC_COEF_C4_MSB);
 
val = hdmi_readb(hdmi, HDMI_CSC_SCALE);
val = ~HDMI_CSC_SCALE_CSCSCALE_MASK;
@@ -1774,8 +1774,6 @@ static int imx_hdmi_register(struct imx_hdmi *hdmi)
 {
int ret;
 
-   drm_mode_connector_attach_encoder(hdmi-connector, hdmi-encoder);
-
hdmi-connector.funcs = imx_hdmi_connector_funcs;
hdmi-encoder.funcs = imx_hdmi_encoder_funcs;
 
@@ -1803,6 +1801,8 @@ static int imx_hdmi_register(struct imx_hdmi *hdmi)
 
hdmi-connector.encoder = hdmi-encoder;
 
+   drm_mode_connector_attach_encoder(hdmi-connector, hdmi-encoder);
+
return 0;
 }
 

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/3] imx-drm: Add mx6 hdmi transmitter support

2013-10-03 Thread Dan Carpenter
On Thu, Oct 03, 2013 at 03:51:25PM -0300, Fabio Estevam wrote:
 This is based on the initial work done by Sascha Hauer and Tony Prisk.
 
 Tested on imx6q-wandboard and imx6q-sabresd boards.
 
 Signed-off-by: Fabio Estevam fabio.este...@freescale.com
 ---
 Changes since v1:
 - Rebased against 3.12-rc3 and fixed header file location
 

It should be done against linux-next as previously mentioned but the
header still needs to be fixed in linux-next I think?

Also it has the following Smatch warnings which are all basically
correct.

drivers/staging/imx-drm/imx-hdmi.c:511 imx_hdmi_update_csc_coeffs() error: 
buffer overflow '(*csc_coeff)[0]' 4 = 4
drivers/staging/imx-drm/imx-hdmi.c:520 imx_hdmi_update_csc_coeffs() error: 
buffer overflow '(*csc_coeff)[1]' 4 = 4
drivers/staging/imx-drm/imx-hdmi.c:529 imx_hdmi_update_csc_coeffs() error: 
buffer overflow '(*csc_coeff)[2]' 4 = 4
drivers/staging/imx-drm/imx-hdmi.c:785 hdmi_phy_i2c_write() info: ignoring 
unreachable code.
drivers/staging/imx-drm/imx-hdmi.c:873 hdmi_phy_configure() warn: unsigned 
'hdmi-hdmi_data.video_mode.mpixelclock' is never less than zero.
drivers/staging/imx-drm/imx-hdmi.c:1537 imx_hdmi_fb_registered() warn: 
inconsistent returns spin_lock:hdmi-irq_lock: locked (1514 
[s32min-(-1),1-s32max]) unlocked (1508 [0], 1537 [0])
drivers/staging/imx-drm/imx-hdmi.c:1537 imx_hdmi_fb_registered() warn: 
inconsistent returns irqsave:flags: locked (1514 [s32min-(-1),1-s32max]) 
unlocked (1508 [0], 1537 [0])
drivers/staging/imx-drm/imx-hdmi.c:1837 imx_hdmi_platform_probe() info: why not 
propagate 'irq' from platform_get_irq() instead of (-22)?

regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel