Commit fc839753 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'imx-drm-next-2015-01-09' of git://git.pengutronix.de/git/pza/linux into drm-next

imx-drm mode fixup support, imx-hdmi bridge conversion and imx-drm cleanup

- Implement mode_fixup for a DI vertical timing limitation
- Use generic DRM OF helpers in DRM core
- Convert imx-hdmi to dw_hdmi drm_bridge and add rockchip
  driver
- Add DC use counter to fix multi-display support
- Simplify handling of DI clock flags
- A few small fixes and cleanup

* tag 'imx-drm-next-2015-01-09' of git://git.pengutronix.de/git/pza/linux: (26 commits)
  imx-drm: core: handling of DI clock flags to ipu_crtc_mode_set()
  gpu: ipu-di: Switch to DIV_ROUND_CLOSEST for DI clock divider calc
  gpu: ipu-v3: Use videomode in struct ipu_di_signal_cfg
  imx-drm: encoder prepare/mode_set must use adjusted mode
  imx-drm: ipuv3-crtc: Implement mode_fixup
  drm_modes: add drm_display_mode_to_videomode
  gpu: ipu-di: remove some non-functional code
  gpu: ipu-di: Add ipu_di_adjust_videomode()
  drm: rockchip: export functions needed by rockchip dw_hdmi bridge driver
  drm: bridge/dw_hdmi: request interrupt only after initializing the mutes
  drm: bridge/dw_hdmi: add rockchip rk3288 support
  dt-bindings: Add documentation for rockchip dw hdmi
  drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare
  drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
  drm: bridge/dw_hdmi: add mode_valid support
  drm: bridge/dw_hdmi: add support for multi-byte register width access
  dt-bindings: add document for dw_hdmi
  drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
  drm: imx: imx-hdmi: split phy configuration to platform driver
  drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode
  ...
parents b2eb0489 d50141d8
DesignWare HDMI bridge bindings
Required properties:
- compatible: platform specific such as:
* "snps,dw-hdmi-tx"
* "fsl,imx6q-hdmi"
* "fsl,imx6dl-hdmi"
* "rockchip,rk3288-dw-hdmi"
- reg: Physical base address and length of the controller's registers.
- interrupts: The HDMI interrupt number
- clocks, clock-names : must have the phandles to the HDMI iahb and isfr clocks,
as described in Documentation/devicetree/bindings/clock/clock-bindings.txt,
the clocks are soc specific, the clock-names should be "iahb", "isfr"
-port@[X]: SoC specific port nodes with endpoint definitions as defined
in Documentation/devicetree/bindings/media/video-interfaces.txt,
please refer to the SoC specific binding document:
* Documentation/devicetree/bindings/drm/imx/hdmi.txt
* Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
Optional properties
- reg-io-width: the width of the reg:1,4, default set to 1 if not present
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
Example:
hdmi: hdmi@0120000 {
compatible = "fsl,imx6q-hdmi";
reg = <0x00120000 0x9000>;
interrupts = <0 115 0x04>;
gpr = <&gpr>;
clocks = <&clks 123>, <&clks 124>;
clock-names = "iahb", "isfr";
ddc-i2c-bus = <&i2c2>;
port@0 {
reg = <0>;
hdmi_mux_0: endpoint {
remote-endpoint = <&ipu1_di0_hdmi>;
};
};
port@1 {
reg = <1>;
hdmi_mux_1: endpoint {
remote-endpoint = <&ipu1_di1_hdmi>;
};
};
};
Rockchip specific extensions to the Synopsys Designware HDMI
================================
Required properties:
- compatible: "rockchip,rk3288-dw-hdmi";
- reg: Physical base address and length of the controller's registers.
- clocks: phandle to hdmi iahb and isfr clocks.
- clock-names: should be "iahb" "isfr"
- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
- interrupts: HDMI interrupt number
- ports: contain a port node with endpoint definitions as defined in
Documentation/devicetree/bindings/media/video-interfaces.txt. For
vopb,set the reg = <0> and set the reg = <1> for vopl.
- reg-io-width: the width of the reg:1,4, the value should be 4 on
rk3288 platform
Optional properties
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
Example:
hdmi: hdmi@ff980000 {
compatible = "rockchip,rk3288-dw-hdmi";
reg = <0xff980000 0x20000>;
reg-io-width = <4>;
ddc-i2c-bus = <&i2c5>;
rockchip,grf = <&grf>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
clock-names = "iahb", "isfr";
status = "disabled";
ports {
hdmi_in: port {
#address-cells = <1>;
#size-cells = <0>;
hdmi_in_vopb: endpoint@0 {
reg = <0>;
remote-endpoint = <&vopb_out_hdmi>;
};
hdmi_in_vopl: endpoint@1 {
reg = <1>;
remote-endpoint = <&vopl_out_hdmi>;
};
};
};
};
......@@ -3,3 +3,8 @@ config DRM_PTN3460
depends on DRM
select DRM_KMS_HELPER
---help---
config DRM_DW_HDMI
tristate
depends on DRM
select DRM_KMS_HELPER
ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
......@@ -837,7 +837,8 @@ enum {
HDMI_PHY_CONF0_PDZ_OFFSET = 7,
HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
HDMI_PHY_CONF0_SPARECTRL = 0x20,
HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
......@@ -1029,4 +1030,5 @@ enum {
HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
};
#endif /* __IMX_HDMI_H__ */
......@@ -615,6 +615,46 @@ void drm_display_mode_from_videomode(const struct videomode *vm,
}
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
/**
* drm_display_mode_to_videomode - fill in @vm using @dmode,
* @dmode: drm_display_mode structure to use as source
* @vm: videomode structure to use as destination
*
* Fills out @vm using the display mode specified in @dmode.
*/
void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
struct videomode *vm)
{
vm->hactive = dmode->hdisplay;
vm->hfront_porch = dmode->hsync_start - dmode->hdisplay;
vm->hsync_len = dmode->hsync_end - dmode->hsync_start;
vm->hback_porch = dmode->htotal - dmode->hsync_end;
vm->vactive = dmode->vdisplay;
vm->vfront_porch = dmode->vsync_start - dmode->vdisplay;
vm->vsync_len = dmode->vsync_end - dmode->vsync_start;
vm->vback_porch = dmode->vtotal - dmode->vsync_end;
vm->pixelclock = dmode->clock * 1000;
vm->flags = 0;
if (dmode->flags & DRM_MODE_FLAG_PHSYNC)
vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
else if (dmode->flags & DRM_MODE_FLAG_NHSYNC)
vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
if (dmode->flags & DRM_MODE_FLAG_PVSYNC)
vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
else if (dmode->flags & DRM_MODE_FLAG_NVSYNC)
vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
if (dmode->flags & DRM_MODE_FLAG_INTERLACE)
vm->flags |= DISPLAY_FLAGS_INTERLACED;
if (dmode->flags & DRM_MODE_FLAG_DBLSCAN)
vm->flags |= DISPLAY_FLAGS_DOUBLESCAN;
if (dmode->flags & DRM_MODE_FLAG_DBLCLK)
vm->flags |= DISPLAY_FLAGS_DOUBLECLK;
}
EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
#ifdef CONFIG_OF
/**
* of_get_drm_display_mode - get a drm_display_mode from devicetree
......
......@@ -49,6 +49,7 @@ config DRM_IMX_IPUV3
config DRM_IMX_HDMI
tristate "Freescale i.MX DRM HDMI"
select DRM_DW_HDMI
depends on DRM_IMX
help
Choose this if you want to use HDMI on i.MX6.
......@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o
obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o
obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
*
* derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/component.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <drm/bridge/dw_hdmi.h>
#include <video/imx-ipu-v3.h>
#include <linux/regmap.h>
#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "imx-drm.h"
struct imx_hdmi {
struct device *dev;
struct drm_encoder encoder;
struct regmap *regmap;
};
static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = {
{
45250000, {
{ 0x01e0, 0x0000 },
{ 0x21e1, 0x0000 },
{ 0x41e2, 0x0000 }
},
}, {
92500000, {
{ 0x0140, 0x0005 },
{ 0x2141, 0x0005 },
{ 0x4142, 0x0005 },
},
}, {
148500000, {
{ 0x00a0, 0x000a },
{ 0x20a1, 0x000a },
{ 0x40a2, 0x000a },
},
}, {
~0UL, {
{ 0x00a0, 0x000a },
{ 0x2001, 0x000f },
{ 0x4002, 0x000f },
},
}
};
static const struct dw_hdmi_curr_ctrl imx_cur_ctr[] = {
/* pixelclk bpp8 bpp10 bpp12 */
{
54000000, { 0x091c, 0x091c, 0x06dc },
}, {
58400000, { 0x091c, 0x06dc, 0x06dc },
}, {
72000000, { 0x06dc, 0x06dc, 0x091c },
}, {
74250000, { 0x06dc, 0x0b5c, 0x091c },
}, {
118800000, { 0x091c, 0x091c, 0x06dc },
}, {
216000000, { 0x06dc, 0x0b5c, 0x091c },
}
};
static const struct dw_hdmi_sym_term imx_sym_term[] = {
/*pixelclk symbol term*/
{ 148500000, 0x800d, 0x0005 },
{ ~0UL, 0x0000, 0x0000 }
};
static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
{
struct device_node *np = hdmi->dev->of_node;
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
if (IS_ERR(hdmi->regmap)) {
dev_err(hdmi->dev, "Unable to get gpr\n");
return PTR_ERR(hdmi->regmap);
}
return 0;
}
static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
{
}
static bool dw_hdmi_imx_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
return true;
}
static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
}
static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
{
struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
}
static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
{
imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
}
static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
.mode_fixup = dw_hdmi_imx_encoder_mode_fixup,
.mode_set = dw_hdmi_imx_encoder_mode_set,
.prepare = dw_hdmi_imx_encoder_prepare,
.commit = dw_hdmi_imx_encoder_commit,
.disable = dw_hdmi_imx_encoder_disable,
};
static struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
.mpll_cfg = imx_mpll_cfg,
.cur_ctr = imx_cur_ctr,
.sym_term = imx_sym_term,
.dev_type = IMX6Q_HDMI,
};
static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
.mpll_cfg = imx_mpll_cfg,
.cur_ctr = imx_cur_ctr,
.sym_term = imx_sym_term,
.dev_type = IMX6DL_HDMI,
};
static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
{ .compatible = "fsl,imx6q-hdmi",
.data = &imx6q_hdmi_drv_data
}, {
.compatible = "fsl,imx6dl-hdmi",
.data = &imx6dl_hdmi_drv_data
},
{},
};
MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
void *data)
{
struct platform_device *pdev = to_platform_device(dev);
const struct dw_hdmi_plat_data *plat_data;
const struct of_device_id *match;
struct drm_device *drm = data;
struct drm_encoder *encoder;
struct imx_hdmi *hdmi;
struct resource *iores;
int irq;
int ret;
if (!pdev->dev.of_node)
return -ENODEV;
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node);
plat_data = match->data;
hdmi->dev = &pdev->dev;
encoder = &hdmi->encoder;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores)
return -ENXIO;
platform_set_drvdata(pdev, hdmi);
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
/*
* If we failed to find the CRTC(s) which this encoder is
* supposed to be connected to, it's because the CRTC has
* not been registered yet. Defer probing, and hope that
* the required CRTC is added later.
*/
if (encoder->possible_crtcs == 0)
return -EPROBE_DEFER;
ret = dw_hdmi_imx_parse_dt(hdmi);
if (ret < 0)
return ret;
drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
DRM_MODE_ENCODER_TMDS);
return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
}
static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
void *data)
{
return dw_hdmi_unbind(dev, master, data);
}
static const struct component_ops dw_hdmi_imx_ops = {
.bind = dw_hdmi_imx_bind,
.unbind = dw_hdmi_imx_unbind,
};
static int dw_hdmi_imx_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &dw_hdmi_imx_ops);
}
static int dw_hdmi_imx_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &dw_hdmi_imx_ops);
return 0;
}
static struct platform_driver dw_hdmi_imx_platform_driver = {
.probe = dw_hdmi_imx_probe,
.remove = dw_hdmi_imx_remove,
.driver = {
.name = "dwhdmi-imx",
.of_match_table = dw_hdmi_imx_dt_ids,
},
};
module_platform_driver(dw_hdmi_imx_platform_driver);
MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:dwhdmi-imx");
......@@ -25,6 +25,7 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_of.h>
#include "imx-drm.h"
......@@ -46,7 +47,6 @@ struct imx_drm_crtc {
struct drm_crtc *crtc;
int pipe;
struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs;
struct device_node *port;
};
static int legacyfb_depth = 16;
......@@ -116,8 +116,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
helper = &imx_crtc->imx_drm_helper_funcs;
if (helper->set_interface_pix_fmt)
return helper->set_interface_pix_fmt(encoder->crtc,
encoder->encoder_type, interface_pix_fmt,
hsync_pin, vsync_pin);
interface_pix_fmt, hsync_pin, vsync_pin);
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
......@@ -365,9 +364,10 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
imx_drm_crtc->pipe = imxdrm->pipes++;
imx_drm_crtc->port = port;
imx_drm_crtc->crtc = crtc;
crtc->port = port;
imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc;
*new_crtc = imx_drm_crtc;
......@@ -408,33 +408,28 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
}
EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
/*
* Find the DRM CRTC possible mask for the connected endpoint.
*
* The encoder possible masks are defined by their position in the
* mode_config crtc_list. This means that CRTCs must not be added
* or removed once the DRM device has been fully initialised.
*/
static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
struct device_node *endpoint)
int imx_drm_encoder_parse_of(struct drm_device *drm,
struct drm_encoder *encoder, struct device_node *np)
{
struct device_node *port;
unsigned i;
uint32_t crtc_mask = drm_of_find_possible_crtcs(drm, np);
port = of_graph_get_remote_port(endpoint);
if (!port)
return 0;
of_node_put(port);
/*
* If we failed to find the CRTC(s) which this encoder is
* supposed to be connected to, it's because the CRTC has
* not been registered yet. Defer probing, and hope that
* the required CRTC is added later.
*/
if (crtc_mask == 0)
return -EPROBE_DEFER;
for (i = 0; i < MAX_CRTC; i++) {
struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
encoder->possible_crtcs = crtc_mask;
if (imx_drm_crtc && imx_drm_crtc->port == port)
return drm_crtc_mask(imx_drm_crtc->crtc);
}
/* FIXME: this is the mask of outputs which can clone this output. */
encoder->possible_clones = ~0;
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
static struct device_node *imx_drm_of_get_next_endpoint(
const struct device_node *parent, struct device_node *prev)
......@@ -445,48 +440,6 @@ static struct device_node *imx_drm_of_get_next_endpoint(
return node;
}
int imx_drm_encoder_parse_of(struct drm_device *drm,
struct drm_encoder *encoder, struct device_node *np)
{
struct imx_drm_device *imxdrm = drm->dev_private;
struct device_node *ep = NULL;
uint32_t crtc_mask = 0;
int i;
for (i = 0; ; i++) {
u32 mask;
ep = imx_drm_of_get_next_endpoint(np, ep);
if (!ep)
break;
mask = imx_drm_find_crtc_mask(imxdrm, ep);
/*
* If we failed to find the CRTC(s) which this encoder is
* supposed to be connected to, it's because the CRTC has
* not been registered yet. Defer probing, and hope that
* the required CRTC is added later.
*/
if (mask == 0)
return -EPROBE_DEFER;
crtc_mask |= mask;
}
of_node_put(ep);
if (i == 0)
return -ENOENT;
encoder->possible_crtcs = crtc_mask;
/* FIXME: this is the mask of outputs which can clone this output. */
encoder->possible_clones = ~0;
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
/*
* @node: device tree node containing encoder input ports
* @encoder: drm_encoder
......@@ -510,7 +463,7 @@ int imx_drm_encoder_get_mux_id(struct device_node *node,
port = of_graph_get_remote_port(ep);
of_node_put(port);
if (port == imx_crtc->port) {
if (port == imx_crtc->crtc->port) {
ret = of_graph_parse_endpoint(ep, &endpoint);
return ret ? ret : endpoint.port;
}
......
......@@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
struct imx_drm_crtc_helper_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
u32 pix_fmt, int hsync_pin, int vsync_pin);
const struct drm_crtc_helper_funcs *crtc_helper_funcs;
const struct drm_crtc_funcs *crtc_funcs;
......
......@@ -163,7 +163,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
struct drm_display_mode *mode = &encoder->crtc->mode;
struct drm_display_mode *mode = &encoder->crtc->hwmode;
u32 pixel_fmt;
unsigned long serial_clk;
unsigned long di_clk = mode->clock * 1000;
......@@ -241,8 +241,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
}
static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
struct drm_display_mode *orig_mode,
struct drm_display_mode *mode)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
......@@ -574,6 +574,8 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
channel->connector.funcs->destroy(&channel->connector);
channel->encoder.funcs->destroy(&channel->encoder);
kfree(channel->edid);
}
}
......
......@@ -307,8 +307,8 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
}
static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
struct drm_display_mode *orig_mode,
struct drm_display_mode *mode)
{
struct imx_tve *tve = enc_to_tve(encoder);
unsigned long rounded_rate;
......
......@@ -46,7 +46,6 @@ struct ipu_crtc {
struct drm_framebuffer *newfb;
int irq;
u32 interface_pix_fmt;
unsigned long di_clkflags;
int di_hsync_pin;
int di_vsync_pin;
};
......@@ -141,47 +140,51 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_encoder *encoder;
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
int ret;
struct ipu_di_signal_cfg sig_cfg = {};
unsigned long encoder_types = 0;
u32 out_pixel_fmt;
int ret;
dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
mode->hdisplay);
dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
mode->vdisplay);
out_pixel_fmt = ipu_crtc->interface_pix_fmt;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
if (encoder->crtc == crtc)
encoder_types |= BIT(encoder->encoder_type);
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
sig_cfg.interlaced = 1;
if (mode->flags & DRM_MODE_FLAG_PHSYNC)