mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 16:29:05 +00:00
omapdrm fixes for 4.14
* fix compilation when compiling omapfb driver * WA for OMAP3 endless sync lost issue * WA for OMAP5 DSI PLL issue * fix analog TV out modecheck -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZnscgAAoJEPo9qoy8lh71MgUQAIJoKbQEcrJWQ01JeYDb58C4 MwwZ8u9Fy3iVGVPM23pCAhf7Rh6f2jvDFFGw/qeZ6Ryi9OiwH6dkmpD7AElUeV03 OqnSGqqZbKVJZYltCQYVGBJ3SOMWON476AyM1w58z9OhZkjizOw5KJPK2e2yh0wP WH8hdX8MkVwgFq9MVrdnu7bJiShVqP37sdAffqNQ6LYuW/kQOdSl20KNNNSKH/D4 NctqaDXI/6EHz3RRLTIzn7ZLRl2qiW3Yp3v+uprOp/yulX7MwFKlZnJNETT9Tf0j 9JHmEXriEZ1gl0Z/pMZOXsdDXhUum7MdiLox5BfNpe/DWPTIkUxmGWBgxKibdHo8 5zzsjODiV42sElTZuVD+VEJZtc+8K6q1C6tFBkmJ/AKz17j+5360o1aWSXpdBj33 gg6mSu+jGWLUH1dnjH74bcq5bQmnLGR6FkGlGy/3a2pWnACMwH+ETSQNwHu1NM/x MWArJQJ1SPuaCAHmhhRFyJwCPxdNDS1MW+mGBoSX21o3qqb69382KAaXXlhU5+9L /MhkYBhet48RdHlseTx+/GxxFkU2gV3sviGm31ts9jHcbJftyTe0aZIc/0w1UWnd 4e43cyvAom6BTQNub4Mi3HnwCXeSUJOhNucgEwf3aTcAISHgD65MerLRcYs58k/t GLSkL7yBCeUPr1UiFjD/ =9KX4 -----END PGP SIGNATURE----- Merge tag 'omapdrm-4.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next omapdrm fixes for 4.14 * fix compilation when compiling omapfb driver * WA for OMAP3 endless sync lost issue * WA for OMAP5 DSI PLL issue * fix analog TV out modecheck * tag 'omapdrm-4.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: ARM: OMAP2+: fix missing variable declaration drm/omap: work-around for omap3 display enable drm/omap: fix i886 work-around drm/omap: fix analog tv-out modecheck
This commit is contained in:
commit
72d45a7603
@ -172,6 +172,7 @@ static int __init omapdss_init_fbdev(void)
|
||||
.set_min_bus_tput = omap_dss_set_min_bus_tput,
|
||||
};
|
||||
struct device_node *node;
|
||||
int r;
|
||||
|
||||
board_data.version = omap_display_get_version();
|
||||
if (board_data.version == OMAPDSS_VER_UNKNOWN) {
|
||||
|
@ -185,6 +185,9 @@ struct dss_pll_hw {
|
||||
bool has_freqsel;
|
||||
bool has_selfreqdco;
|
||||
bool has_refsel;
|
||||
|
||||
/* DRA7 errata i886: use high N & M to avoid jitter */
|
||||
bool errata_i886;
|
||||
};
|
||||
|
||||
struct dss_pll {
|
||||
|
@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
|
||||
dss_pll_calc_func func, void *data)
|
||||
{
|
||||
const struct dss_pll_hw *hw = pll->hw;
|
||||
int n, n_min, n_max;
|
||||
int m, m_min, m_max;
|
||||
int n, n_start, n_stop, n_inc;
|
||||
int m, m_start, m_stop, m_inc;
|
||||
unsigned long fint, clkdco;
|
||||
unsigned long pll_hw_max;
|
||||
unsigned long fint_hw_min, fint_hw_max;
|
||||
@ -226,22 +226,33 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
|
||||
fint_hw_min = hw->fint_min;
|
||||
fint_hw_max = hw->fint_max;
|
||||
|
||||
n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
|
||||
n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max);
|
||||
n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
|
||||
n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
|
||||
n_inc = 1;
|
||||
|
||||
if (hw->errata_i886) {
|
||||
swap(n_start, n_stop);
|
||||
n_inc = -1;
|
||||
}
|
||||
|
||||
pll_max = pll_max ? pll_max : ULONG_MAX;
|
||||
|
||||
/* Try to find high N & M to avoid jitter (DRA7 errata i886) */
|
||||
for (n = n_max; n >= n_min; --n) {
|
||||
for (n = n_start; n != n_stop; n += n_inc) {
|
||||
fint = clkin / n;
|
||||
|
||||
m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
|
||||
m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
|
||||
1ul);
|
||||
m_max = min3((unsigned)(pll_max / fint / 2),
|
||||
m_stop = min3((unsigned)(pll_max / fint / 2),
|
||||
(unsigned)(pll_hw_max / fint / 2),
|
||||
hw->m_max);
|
||||
m_inc = 1;
|
||||
|
||||
for (m = m_max; m >= m_min; --m) {
|
||||
if (hw->errata_i886) {
|
||||
swap(m_start, m_stop);
|
||||
m_inc = -1;
|
||||
}
|
||||
|
||||
for (m = m_start; m != m_stop; m += m_inc) {
|
||||
clkdco = 2 * m * fint;
|
||||
|
||||
if (func(n, m, fint, clkdco, data))
|
||||
|
@ -263,6 +263,12 @@ static const struct venc_config venc_config_pal_bdghi = {
|
||||
.fid_ext_start_y__fid_ext_offset_y = 0x01380005,
|
||||
};
|
||||
|
||||
enum venc_videomode {
|
||||
VENC_MODE_UNKNOWN,
|
||||
VENC_MODE_PAL,
|
||||
VENC_MODE_NTSC,
|
||||
};
|
||||
|
||||
static const struct videomode omap_dss_pal_vm = {
|
||||
.hactive = 720,
|
||||
.vactive = 574,
|
||||
@ -297,6 +303,24 @@ static const struct videomode omap_dss_ntsc_vm = {
|
||||
DISPLAY_FLAGS_SYNC_NEGEDGE,
|
||||
};
|
||||
|
||||
static enum venc_videomode venc_get_videomode(const struct videomode *vm)
|
||||
{
|
||||
if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
|
||||
return VENC_MODE_UNKNOWN;
|
||||
|
||||
if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
|
||||
vm->hactive == omap_dss_pal_vm.hactive &&
|
||||
vm->vactive == omap_dss_pal_vm.vactive)
|
||||
return VENC_MODE_PAL;
|
||||
|
||||
if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
|
||||
vm->hactive == omap_dss_ntsc_vm.hactive &&
|
||||
vm->vactive == omap_dss_ntsc_vm.vactive)
|
||||
return VENC_MODE_NTSC;
|
||||
|
||||
return VENC_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
@ -423,14 +447,14 @@ static void venc_runtime_put(void)
|
||||
|
||||
static const struct venc_config *venc_timings_to_config(struct videomode *vm)
|
||||
{
|
||||
if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
|
||||
switch (venc_get_videomode(vm)) {
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
case VENC_MODE_PAL:
|
||||
return &venc_config_pal_trm;
|
||||
|
||||
if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
|
||||
case VENC_MODE_NTSC:
|
||||
return &venc_config_ntsc_trm;
|
||||
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int venc_power_on(struct omap_dss_device *dssdev)
|
||||
@ -541,15 +565,28 @@ static void venc_display_disable(struct omap_dss_device *dssdev)
|
||||
static void venc_set_timings(struct omap_dss_device *dssdev,
|
||||
struct videomode *vm)
|
||||
{
|
||||
struct videomode actual_vm;
|
||||
|
||||
DSSDBG("venc_set_timings\n");
|
||||
|
||||
mutex_lock(&venc.venc_lock);
|
||||
|
||||
switch (venc_get_videomode(vm)) {
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
case VENC_MODE_PAL:
|
||||
actual_vm = omap_dss_pal_vm;
|
||||
break;
|
||||
case VENC_MODE_NTSC:
|
||||
actual_vm = omap_dss_ntsc_vm;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset WSS data when the TV standard changes. */
|
||||
if (memcmp(&venc.vm, vm, sizeof(*vm)))
|
||||
if (memcmp(&venc.vm, &actual_vm, sizeof(actual_vm)))
|
||||
venc.wss_data = 0;
|
||||
|
||||
venc.vm = *vm;
|
||||
venc.vm = actual_vm;
|
||||
|
||||
dispc_set_tv_pclk(13500000);
|
||||
|
||||
@ -561,13 +598,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
|
||||
{
|
||||
DSSDBG("venc_check_timings\n");
|
||||
|
||||
if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
|
||||
switch (venc_get_videomode(vm)) {
|
||||
case VENC_MODE_PAL:
|
||||
case VENC_MODE_NTSC:
|
||||
return 0;
|
||||
|
||||
if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void venc_get_timings(struct omap_dss_device *dssdev,
|
||||
|
@ -130,6 +130,8 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
|
||||
.mX_lsb[3] = 5,
|
||||
|
||||
.has_refsel = true,
|
||||
|
||||
.errata_i886 = true,
|
||||
};
|
||||
|
||||
struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
|
||||
|
@ -84,23 +84,36 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
|
||||
/* Apply the atomic update. */
|
||||
drm_atomic_helper_commit_modeset_disables(dev, old_state);
|
||||
|
||||
/* With the current dss dispc implementation we have to enable
|
||||
* the new modeset before we can commit planes. The dispc ovl
|
||||
* configuration relies on the video mode configuration been
|
||||
* written into the HW when the ovl configuration is
|
||||
* calculated.
|
||||
*
|
||||
* This approach is not ideal because after a mode change the
|
||||
* plane update is executed only after the first vblank
|
||||
* interrupt. The dispc implementation should be fixed so that
|
||||
* it is able use uncommitted drm state information.
|
||||
*/
|
||||
drm_atomic_helper_commit_modeset_enables(dev, old_state);
|
||||
omap_atomic_wait_for_completion(dev, old_state);
|
||||
if (priv->omaprev != 0x3430) {
|
||||
/* With the current dss dispc implementation we have to enable
|
||||
* the new modeset before we can commit planes. The dispc ovl
|
||||
* configuration relies on the video mode configuration been
|
||||
* written into the HW when the ovl configuration is
|
||||
* calculated.
|
||||
*
|
||||
* This approach is not ideal because after a mode change the
|
||||
* plane update is executed only after the first vblank
|
||||
* interrupt. The dispc implementation should be fixed so that
|
||||
* it is able use uncommitted drm state information.
|
||||
*/
|
||||
drm_atomic_helper_commit_modeset_enables(dev, old_state);
|
||||
omap_atomic_wait_for_completion(dev, old_state);
|
||||
|
||||
drm_atomic_helper_commit_planes(dev, old_state, 0);
|
||||
drm_atomic_helper_commit_planes(dev, old_state, 0);
|
||||
|
||||
drm_atomic_helper_commit_hw_done(old_state);
|
||||
drm_atomic_helper_commit_hw_done(old_state);
|
||||
} else {
|
||||
/*
|
||||
* OMAP3 DSS seems to have issues with the work-around above,
|
||||
* resulting in endless sync losts if a crtc is enabled without
|
||||
* a plane. For now, skip the WA for OMAP3.
|
||||
*/
|
||||
drm_atomic_helper_commit_planes(dev, old_state, 0);
|
||||
|
||||
drm_atomic_helper_commit_modeset_enables(dev, old_state);
|
||||
|
||||
drm_atomic_helper_commit_hw_done(old_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for completion of the page flips to ensure that old buffers
|
||||
|
Loading…
x
Reference in New Issue
Block a user