gpu: ipu-v3: Implement use counter for ipu_dc_enable(), ipu_dc_disable()

The functions ipu_dc_enable() and ipu_dc_disable() enable/disable the DC
globally in the IPU_CONF register, but the DC is used by multiple clients
on different DC channels. So make sure to only disable/enable the DC
globally based on a use counter.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: fix HDMI timing issues

On some monitors, with high resolution(1920x1080), HDMI is not working,
some resolution have pixel column truncation problem
(shows 1280x1022 instead of 1280x1024), which will result in really strange
picture on some monitors.

This Patch aims to fix these HDMI timing issues.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Deepak Das <deepak_das@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: Update DP sync SRM always in ipu_dp_enable_channel()

In Freescale kernels, when a DP channel is enabled, the DP sync
SRM is updated for both background and foreground DP channels. Do
the same.

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: Change signal names in struct ipu_di_signal_cfg

This patch changes signal names in struct ipu_di_signal_cfg
as per the industry standard names, and renames fields that
were using CamelCase.

Signed-off-by: Deepak Das <deepak_das@mentor.com>
Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-cpmem: Add ipu_cpmem_set_uv_offset()

Adds ipu_cpmem_set_uv_offset(), to set planar U/V offsets.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-dp: Create CSC coefficient tables

Move the inlined CSC coefficients out of ipu_dp_csc_init() and into
static const tables.

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

Adds the function ipu_dp_set_color_key(), which sets up a color key
value for a DP foreground plane.

ipu_dp_set_color_key() accepts a color key value in RGB24 format.
If the combiner unit colorspace is YUV, the key must be converted
to YUV444, using the same CSC coefficients as programmed in the DP.

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

Adds the function ipu_dp_set_gamma_correction(), which programs the
piecewise linear curve that approximates a gamma correction curve.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
gpu: ipu-v3: Add support for dynamic DC interface pixel maps

Adds support to ipu-dc to dynamically create new display interface
pixel mappings.

The mappings are formally defined by a struct ipu_dc_if_map, which is
passed to ipu_dc_init_sync().

The ipu-dc maintains a list of the currently programmed mappings.
Some mappings are pre-loaded at probe time (RGB24, BGR24, GBR24,
RGB565, BGR666, and "LVDS666").

If the map pointer to ipu_dc_init_sync() is not NULL, a new mapping
is created, otherwise previously loaded mappings will be searched based
on the passed pixel_fmt.

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-v3: Add ipu_dc_uninit_sync()

Adds the function ipu_dc_uninit_sync() which tears down
ipu_dc_init_sync().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Muzaffar Mahmood <muzaffar_mahmood@mentor.com>
gpu: ipu-v3: Add ipu_dp_uninit_channel()

Adds the function ipu_dp_uninit_channel() which tears down
ipu_dp_setup_channel().

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