gpu: ipu-di: Add ipu_di_adjust_videomode()

On some monitors, high resolution modes are not working, exhibiting
pixel column truncation problems (for example, 1280x1024 displays as
1280x1022).

The function ipu_di_adjust_videomode() aims to fix these issues by
adjusting a passed videomode to IPU restrictions. The function can
be called from the drm_crtc_helper_funcs->mode_fixup() methods.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Deepak Das <deepak_das@mentor.com>
Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-di: remove some non-functional code

h_total and v_total were calculated in ipu_di_init_sync_panel()
but never actually used. Remove.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
drm_modes: add videomode_from_drm_display_mode

Add conversion from drm_display_mode to videomode.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
imx-drm: ipuv3-crtc: Implement mode_fixup

Ask the IPU display interface, via ipu_di_adjust_videomode(), to
adjust a video mode to meet any DI restrictions. The function takes
a subsystem independent videomode, so the drm_display_mode must be
converted to videomode first, and then the adjusted mode converted
back to a drm_display_mode.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
imx-drm: encoder mode_set must use adjusted mode

The encoder ->mode_set() methods need to use the hw adjusted mode,
not the original mode.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Fix BGR interface pix fmts, add RGB666

The interface pixel maps defined for BGR666 and LVDS666 in ipu-dc
were actually RGB order, fix them to be actual BGR order.

This means any users of the original BGR666 or LVDS666 mappings
were actually requesting RGB order mappings. So we need to add a
real RGB666 mapping to ipu-dc and then modify the users of "BGR666"
to ask for RGB666 instead. Those users are imx-ldb and imx-parallel
(there were no users of LVDS666).

Also modify the fsl-imx-drm.txt bindings docs to change the "bgr666"
supported interface format to "rgb666".

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
ARM: dts: mx5: bgr666 interface-pix-fmt is actually rgb666

The BGR666 interface pixel map defined in ipu-dc was actually an
RGB666 format, so the M53EVK and apf51dev reference boards were
actually requesting RGB666. This has been corrected in ipu-dc, and
in addition the real RGB666 format has been added, so change the
interface-pix-fmt name to "rgb666".

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Split out DI clock enable/disable

DI clock enable/disable is moved out of ipu_di_enable() and ipu_di_disable()
and into (new) ipu_di_enable_clock() and ipu_di_disable_clock(). So
ipu_di_enable() and ipu_di_disable() are now pure module enable/disable.

The purpose of this change is to more closely emulate the display mode
setting sequence in FSL kernels, which enable and disable the DI
clock as the very last steps during legacy fbdev set_par().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Move DI waveform counter enable/disable to ipu-di

Move the DI waveform counter enable/disable out of
ipu_module_enable()/disable(). This should be carried out
when enabling/disabling the DI pixel clock.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Allow burstsize of 20 in ipu_dmfc_setup_channel()

IDMAC channels can have a burtsize of 20 pixels, so allow for that in
ipu_dmfc_setup_channel().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Remove ipu_dmfc_init_channel()

The function ipu_dmfc_init_channel() sets the "WAIT4EOT" mode according
to the line width and the DMFC channel's FIFO size (the slots parameter).
But this can only happen after slots has been calculated in
ipu_dmfc_alloc_bandwidth().

Fix by renaming ipu_dmfc_init_channel() to a static dmfc_set_wait_eot()
which is called at the end of ipu_dmfc_alloc_bandwidth(), after slots
has been calculated.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Consolidate mutex lock in ipu_dmfc_alloc_bandwidth()

The dmfc mutex was being acquired in ipu_dmfc_free_bandwidth(), freed,
then immediately re-acquired in ipu_dmfc_alloc_bandwidth(). Acquire
the lock once at the beginning of ipu_dmfc_alloc_bandwidth().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-di: Move ipu pointer init

Move the init of di->ipu pointer to near top of ipu_di_init().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-di: Set rate of DI pre clock

This patch sets the rate of the DI pre clock to support a much wider
range of pixel clock frequencies.

It does this by calculating two values for the pre-clk rate: a
rate that is a whole integer multiple of the pixel clock, and a rate
that is a half-integer multiple. It then programs whichever rate
comes closest to generating the desired pixel clock, and uses the
corresponding integer or half-integer divider.

The reason only whole or half integer DI dividers are used is because
of a chip bug in the fractional part of DI Base Sync Clock Gen 0 register
(see discussion in FSL community site at
https://community.freescale.com/thread/308577).

Quoting from that thread:

"Pixel IPU clock for Display has high jitter and does not have 50% duty cycle.
This is expected behavior, when the clock divider is set to a value that is not
an integer. When the divider is set to a non-integer value, the average
frequency of the clock will be correct, but the clock will jitter."

According to our experimentation, only 0x8 for the fractional part seems
to generate clock waveforms that are tolerated by most displays (this
hasn't been proved officially).

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
gpu: ipu-v3: Use videomode in struct ipu_di_signal_cfg

This patch changes struct ipu_di_signal_cfg to use struct videomode
to define video timings and flags.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Pass struct ipu_dc to enable/disable

Pass the pointer to DC channel to ipu_dc_enable() and ipu_dc_disable(),
to be more consistent with the other ipu-dc APIs.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Pass struct ipu_dp to enable/disable

Pass the pointer to DP channel to ipu_dp_enable() and ipu_dp_disable(),
to be more consistent with the other ipu-dp APIs.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-dc: Enumerate the DC channel names

Define the names of the DC channels, and reference them in ipu-dc.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-cpmem: Pass drm fourcc to ipu_cpmem_set_yuv_*

Pass a drm pixel format fourcc to ipu_cpmem_set_yuv_interleaved(),
ipu_cpmem_set_yuv_planar_full(), and ipu_cpmem_set_yuv_planar(),
instead of a v4l2 pixel format. The remaining cpmem API that still
accepts a v4l2 format is now only ipu_cpmem_set_image(), since this
function is called by v4l2 drivers.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-cpmem: Support YVU422

Add simple hooks to support YVU422 in cpmem.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>