Commit 64c026e2 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'exynos-drm-next' of...

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

Inki writes:
      This is initial pull request for Exynos. It includes a big change
       that it makes drm_display_mode for timings parameters to be used
       for exynos4 and exynos5 commonly and cleans up unnecessary codes.
       And also it adds device tree support for fimd to get timing values
       and interrupt source from dts file.

       In addition, one more patch, device tree support feature for Exynos
       FIMC, is being reviewed. This patch was posted a little ago like below,
            http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg17568.html

       So we are going to request git pull one more time after reviewed.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
  drm/exynos: prepare FIMD clocks
  Revert "of/exynos_g2d: Add Bindings for exynos G2D driver"
  drm/exynos: drm_connector: Fix error check condition
  drm/exynos: drm_rotator: Fix incorrect usage of IS_ERR_OR_NULL
  drm/exynos: mixer: Fix incorrect usage of IS_ERR_OR_NULL
  drm/exynos: hdmi: Fix incorrect usage of IS_ERR_OR_NULL
  drm/exynos: change the method for getting the interrupt
  drm/exynos: enable OF_VIDEOMODE and FB_MODE_HELPERS for exynos drm fimd
  drm/exynos: Add display-timing node parsing using video helper function
  drm/exynos: hdmi: move mode_fixup to drm common hdmi
  drm/exynos: hdmi: using drm_display_mode timings for exynos4
parents f0aa848f b4e3a3e8
Samsung 2D Graphic Accelerator using DRM frame work
Samsung FIMG2D is a graphics 2D accelerator which supports Bit Block Transfer.
We set the drawing-context registers for configuring rendering parameters and
then start rendering.
This driver is for SOCs which contain G2D IPs with version 4.1.
Required properties:
-compatible:
should be "samsung,exynos-g2d-41".
-reg:
physical base address of the controller and length
of memory mapped region.
-interrupts:
interrupt combiner values.
Example:
g2d {
compatible = "samsung,exynos-g2d-41";
reg = <0x10850000 0x1000>;
interrupts = <0 91 0>;
};
......@@ -24,7 +24,9 @@ config DRM_EXYNOS_DMABUF
config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
depends on OF && DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
select OF_VIDEOMODE
select FB_MODE_HELPERS
help
Choose this option if you want to use Exynos FIMD for DRM.
......
......@@ -124,7 +124,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
}
count = drm_add_edid_modes(connector, edid);
if (count < 0) {
if (!count) {
DRM_ERROR("Add edid modes failed %d\n", count);
goto out;
}
......
......@@ -20,6 +20,7 @@
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <video/of_display_timing.h>
#include <video/samsung_fimd.h>
#include <drm/exynos_drm.h>
......@@ -884,11 +885,26 @@ static int fimd_probe(struct platform_device *pdev)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (pdev->dev.of_node) {
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
DRM_ERROR("memory allocation for pdata failed\n");
return -ENOMEM;
}
ret = of_get_fb_videomode(dev->of_node, &pdata->panel.timing,
OF_USE_NATIVE_MODE);
if (ret) {
DRM_ERROR("failed: of_get_fb_videomode() : %d\n", ret);
return ret;
}
} else {
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(dev, "no platform data specified\n");
DRM_ERROR("no platform data specified\n");
return -EINVAL;
}
}
panel = &pdata->panel;
if (!panel) {
......@@ -918,7 +934,7 @@ static int fimd_probe(struct platform_device *pdev)
if (IS_ERR(ctx->regs))
return PTR_ERR(ctx->regs);
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
if (!res) {
dev_err(dev, "irq request failed.\n");
return -ENXIO;
......@@ -933,6 +949,16 @@ static int fimd_probe(struct platform_device *pdev)
return ret;
}
ret = clk_prepare(ctx->bus_clk);
if (ret < 0)
return ret;
ret = clk_prepare(ctx->lcd_clk);
if (ret < 0) {
clk_unprepare(ctx->bus_clk);
return ret;
}
ctx->vidcon0 = pdata->vidcon0;
ctx->vidcon1 = pdata->vidcon1;
ctx->default_win = pdata->default_win;
......@@ -980,8 +1006,8 @@ static int fimd_remove(struct platform_device *pdev)
if (ctx->suspended)
goto out;
clk_disable(ctx->lcd_clk);
clk_disable(ctx->bus_clk);
clk_unprepare(ctx->lcd_clk);
clk_unprepare(ctx->bus_clk);
pm_runtime_set_suspended(dev);
pm_runtime_put_sync(dev);
......
......@@ -205,13 +205,45 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
struct drm_display_mode *m;
int mode_ok;
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_ops && hdmi_ops->mode_fixup)
hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
adjusted_mode);
drm_mode_set_crtcinfo(adjusted_mode, 0);
mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
/* just return if user desired mode exists. */
if (mode_ok == 0)
return;
/*
* otherwise, find the most suitable mode among modes and change it
* to adjusted_mode.
*/
list_for_each_entry(m, &connector->modes, head) {
mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
if (mode_ok == 0) {
struct drm_mode_object base;
struct list_head head;
DRM_INFO("desired mode doesn't exist so\n");
DRM_INFO("use the most suitable mode among modes.\n");
DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
m->hdisplay, m->vdisplay, m->vrefresh);
/* preserve display mode header while copying. */
head = adjusted_mode->head;
base = adjusted_mode->base;
memcpy(adjusted_mode, m, sizeof(*m));
adjusted_mode->head = head;
adjusted_mode->base = base;
break;
}
}
}
static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
......
......@@ -36,9 +36,6 @@ struct exynos_hdmi_ops {
int (*power_on)(void *ctx, int mode);
/* manager */
void (*mode_fixup)(void *ctx, struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void (*mode_set)(void *ctx, void *mode);
void (*get_max_resol)(void *ctx, unsigned int *width,
unsigned int *height);
......
......@@ -674,7 +674,7 @@ static int rotator_probe(struct platform_device *pdev)
}
rot->clock = devm_clk_get(dev, "rotator");
if (IS_ERR_OR_NULL(rot->clock)) {
if (IS_ERR(rot->clock)) {
dev_err(dev, "failed to get clock\n");
ret = PTR_ERR(rot->clock);
goto err_clk_get;
......
......@@ -108,7 +108,20 @@ struct hdmi_tg_regs {
u8 tg_3d[1];
};
struct hdmi_core_regs {
struct hdmi_v13_core_regs {
u8 h_blank[2];
u8 v_blank[3];
u8 h_v_line[3];
u8 vsync_pol[1];
u8 int_pro_mode[1];
u8 v_blank_f[3];
u8 h_sync_gen[3];
u8 v_sync_gen1[3];
u8 v_sync_gen2[3];
u8 v_sync_gen3[3];
};
struct hdmi_v14_core_regs {
u8 h_blank[2];
u8 v2_blank[2];
u8 v1_blank[2];
......@@ -147,11 +160,23 @@ struct hdmi_core_regs {
u8 vact_space_6[2];
};
struct hdmi_v13_conf {
struct hdmi_v13_core_regs core;
struct hdmi_tg_regs tg;
};
struct hdmi_v14_conf {
int pixel_clock;
struct hdmi_core_regs core;
struct hdmi_v14_core_regs core;
struct hdmi_tg_regs tg;
};
struct hdmi_conf_regs {
int pixel_clock;
int cea_video_id;
union {
struct hdmi_v13_conf v13_conf;
struct hdmi_v14_conf v14_conf;
} conf;
};
struct hdmi_context {
......@@ -169,9 +194,8 @@ struct hdmi_context {
struct i2c_client *ddc_port;
struct i2c_client *hdmiphy_port;
/* current hdmiphy conf index */
int cur_conf;
struct hdmi_v14_conf mode_conf;
/* current hdmiphy conf regs */
struct hdmi_conf_regs mode_conf;
struct hdmi_resources res;
......@@ -180,292 +204,60 @@ struct hdmi_context {
enum hdmi_type type;
};
/* HDMI Version 1.3 */
static const u8 hdmiphy_v13_conf27[32] = {
struct hdmiphy_config {
int pixel_clock;
u8 conf[32];
};
/* list of phy config settings */
static const struct hdmiphy_config hdmiphy_v13_configs[] = {
{
.pixel_clock = 27000000,
.conf = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
};
static const u8 hdmiphy_v13_conf27_027[32] = {
},
},
{
.pixel_clock = 27027000,
.conf = {
0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
};
static const u8 hdmiphy_v13_conf74_175[32] = {
},
},
{
.pixel_clock = 74176000,
.conf = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
};
static const u8 hdmiphy_v13_conf74_25[32] = {
},
},
{
.pixel_clock = 74250000,
.conf = {
0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
};
static const u8 hdmiphy_v13_conf148_5[32] = {
},
},
{
.pixel_clock = 148500000,
.conf = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
};
struct hdmi_v13_tg_regs {
u8 cmd;
u8 h_fsz_l;
u8 h_fsz_h;
u8 hact_st_l;
u8 hact_st_h;
u8 hact_sz_l;
u8 hact_sz_h;
u8 v_fsz_l;
u8 v_fsz_h;
u8 vsync_l;
u8 vsync_h;
u8 vsync2_l;
u8 vsync2_h;
u8 vact_st_l;
u8 vact_st_h;
u8 vact_sz_l;
u8 vact_sz_h;
u8 field_chg_l;
u8 field_chg_h;
u8 vact_st2_l;
u8 vact_st2_h;
u8 vsync_top_hdmi_l;
u8 vsync_top_hdmi_h;
u8 vsync_bot_hdmi_l;
u8 vsync_bot_hdmi_h;
u8 field_top_hdmi_l;
u8 field_top_hdmi_h;
u8 field_bot_hdmi_l;
u8 field_bot_hdmi_h;
};
struct hdmi_v13_core_regs {
u8 h_blank[2];
u8 v_blank[3];
u8 h_v_line[3];
u8 vsync_pol[1];
u8 int_pro_mode[1];
u8 v_blank_f[3];
u8 h_sync_gen[3];
u8 v_sync_gen1[3];
u8 v_sync_gen2[3];
u8 v_sync_gen3[3];
};
struct hdmi_v13_preset_conf {
struct hdmi_v13_core_regs core;
struct hdmi_v13_tg_regs tg;
};
struct hdmi_v13_conf {
int width;
int height;
int vrefresh;
bool interlace;
int cea_video_id;
const u8 *hdmiphy_data;
const struct hdmi_v13_preset_conf *conf;
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
.core = {
.h_blank = {0x8a, 0x00},
.v_blank = {0x0d, 0x6a, 0x01},
.h_v_line = {0x0d, 0xa2, 0x35},
.vsync_pol = {0x01},
.int_pro_mode = {0x00},
.v_blank_f = {0x00, 0x00, 0x00},
.h_sync_gen = {0x0e, 0x30, 0x11},
.v_sync_gen1 = {0x0f, 0x90, 0x00},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x5a, 0x03, /* h_fsz */
0x8a, 0x00, 0xd0, 0x02, /* hact */
0x0d, 0x02, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x2d, 0x00, 0xe0, 0x01, /* vact */
0x33, 0x02, /* field_chg */
0x49, 0x02, /* vact_st2 */
0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
.core = {
.h_blank = {0x72, 0x01},
.v_blank = {0xee, 0xf2, 0x00},
.h_v_line = {0xee, 0x22, 0x67},
.vsync_pol = {0x00},
.int_pro_mode = {0x00},
.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
.h_sync_gen = {0x6c, 0x50, 0x02},
.v_sync_gen1 = {0x0a, 0x50, 0x00},
.v_sync_gen2 = {0x01, 0x10, 0x00},
.v_sync_gen3 = {0x01, 0x10, 0x00},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x72, 0x06, /* h_fsz */
0x71, 0x01, 0x01, 0x05, /* hact */
0xee, 0x02, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x1e, 0x00, 0xd0, 0x02, /* vact */
0x33, 0x02, /* field_chg */
0x49, 0x02, /* vact_st2 */
0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
.core = {
.h_blank = {0xd0, 0x02},
.v_blank = {0x32, 0xB2, 0x00},
.h_v_line = {0x65, 0x04, 0xa5},
.vsync_pol = {0x00},
.int_pro_mode = {0x01},
.v_blank_f = {0x49, 0x2A, 0x23},
.h_sync_gen = {0x0E, 0xEA, 0x08},
.v_sync_gen1 = {0x07, 0x20, 0x00},
.v_sync_gen2 = {0x39, 0x42, 0x23},
.v_sync_gen3 = {0x38, 0x87, 0x73},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x50, 0x0A, /* h_fsz */
0xCF, 0x02, 0x81, 0x07, /* hact */
0x65, 0x04, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x16, 0x00, 0x1c, 0x02, /* vact */
0x33, 0x02, /* field_chg */
0x49, 0x02, /* vact_st2 */
0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
.core = {
.h_blank = {0xd0, 0x02},
.v_blank = {0x65, 0x6c, 0x01},
.h_v_line = {0x65, 0x04, 0xa5},
.vsync_pol = {0x00},
.int_pro_mode = {0x00},
.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
.h_sync_gen = {0x0e, 0xea, 0x08},
.v_sync_gen1 = {0x09, 0x40, 0x00},
.v_sync_gen2 = {0x01, 0x10, 0x00},
.v_sync_gen3 = {0x01, 0x10, 0x00},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x50, 0x0A, /* h_fsz */
0xCF, 0x02, 0x81, 0x07, /* hact */
0x65, 0x04, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x2d, 0x00, 0x38, 0x04, /* vact */
0x33, 0x02, /* field_chg */
0x48, 0x02, /* vact_st2 */
0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
.core = {
.h_blank = {0x18, 0x01},
.v_blank = {0x32, 0xB2, 0x00},
.h_v_line = {0x65, 0x84, 0x89},
.vsync_pol = {0x00},
.int_pro_mode = {0x01},
.v_blank_f = {0x49, 0x2A, 0x23},
.h_sync_gen = {0x56, 0x08, 0x02},
.v_sync_gen1 = {0x07, 0x20, 0x00},
.v_sync_gen2 = {0x39, 0x42, 0x23},
.v_sync_gen3 = {0xa4, 0x44, 0x4a},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x98, 0x08, /* h_fsz */
0x17, 0x01, 0x81, 0x07, /* hact */
0x65, 0x04, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x16, 0x00, 0x1c, 0x02, /* vact */
0x33, 0x02, /* field_chg */
0x49, 0x02, /* vact_st2 */
0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
.core = {
.h_blank = {0x18, 0x01},
.v_blank = {0x65, 0x6c, 0x01},
.h_v_line = {0x65, 0x84, 0x89},
.vsync_pol = {0x00},
.int_pro_mode = {0x00},
.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
.h_sync_gen = {0x56, 0x08, 0x02},
.v_sync_gen1 = {0x09, 0x40, 0x00},
.v_sync_gen2 = {0x01, 0x10, 0x00},
.v_sync_gen3 = {0x01, 0x10, 0x00},
/* other don't care */
},
.tg = {
0x00, /* cmd */
0x98, 0x08, /* h_fsz */
0x17, 0x01, 0x81, 0x07, /* hact */
0x65, 0x04, /* v_fsz */
0x01, 0x00, 0x33, 0x02, /* vsync */
0x2d, 0x00, 0x38, 0x04, /* vact */
0x33, 0x02, /* field_chg */
0x48, 0x02, /* vact_st2 */
0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
0x01, 0x00, 0x33, 0x02, /* field top/bot */
},
};
static const struct hdmi_v13_conf hdmi_v13_confs[] = {
{ 1280, 720, 60, false, 4, hdmiphy_v13_conf74_25,
&hdmi_v13_conf_720p60 },
{ 1280, 720, 50, false, 19, hdmiphy_v13_conf74_25,
&hdmi_v13_conf_720p60 },
{ 720, 480, 60, false, 3, hdmiphy_v13_conf27_027,
&hdmi_v13_conf_480p },
{ 1920, 1080, 50, true, 20, hdmiphy_v13_conf74_25,
&hdmi_v13_conf_1080i50 },
{ 1920, 1080, 50, false, 31, hdmiphy_v13_conf148_5,
&hdmi_v13_conf_1080p50 },
{ 1920, 1080, 60, true, 5, hdmiphy_v13_conf74_25,
&hdmi_v13_conf_1080i60 },
{ 1920, 1080, 60, false, 16, hdmiphy_v13_conf148_5,
&hdmi_v13_conf_1080p60 },
};
/* HDMI Version 1.4 */
struct hdmiphy_config {
int pixel_clock;
u8 conf[32];
};
/* list of all required phy config settings */
static const struct hdmiphy_config hdmiphy_v14_configs[] = {
{
.pixel_clock = 25200000,
......@@ -873,22 +665,6 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
hdmi_v14_regs_dump(hdata, prefix);
}
static int hdmi_v13_conf_index(struct drm_display_mode *mode)
{
int i;
for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
if (hdmi_v13_confs[i].width == mode->hdisplay &&
hdmi_v13_confs[i].height == mode->vdisplay &&
hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
hdmi_v13_confs[i].interlace ==
((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
true : false))
return i;
return -EINVAL;
}
static u8 hdmi_chksum(struct hdmi_context *hdata,
u32 start, u8 len, u32 hdr_sum)
{
......@@ -943,11 +719,7 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), aspect_ratio |
AVI_SAME_AS_PIC_ASPECT_RATIO);
if (hdata->type == HDMI_TYPE13)
vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id;
else
vic = hdata->mode_conf.cea_video_id;
hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
......@@ -1000,63 +772,34 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
return raw_edid;
}
static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
{
int i;
const struct hdmiphy_config *confs;
int count, i;
DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
check_timing->xres, check_timing->yres,
check_timing->refresh, (check_timing->vmode &
FB_VMODE_INTERLACED) ? true : false);
for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
if (hdmi_v13_confs[i].width == check_timing->xres &&
hdmi_v13_confs[i].height == check_timing->yres &&
hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
hdmi_v13_confs[i].interlace ==
((check_timing->vmode & FB_VMODE_INTERLACED) ?
true : false))
return 0;
/* TODO */
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
if (hdata->type == HDMI_TYPE13) {
confs = hdmiphy_v13_configs;
count = ARRAY_SIZE(hdmiphy_v13_configs);
} else if (hdata->type == HDMI_TYPE14) {
confs = hdmiphy_v14_configs;
count = ARRAY_SIZE(hdmiphy_v14_configs);
} else
return -EINVAL;
}
static int hdmi_v14_find_phy_conf(int pixel_clock)
{
int i;
for (i = 0; i < ARRAY_SIZE(hdmiphy_v14_configs); i++) {
if (hdmiphy_v14_configs[i].pixel_clock == pixel_clock)
for (i = 0; i < count; i++)
if (confs[i].pixel_clock == pixel_clock)
return i;
}
DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
return -EINVAL;
}
static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
{
int i;
DRM_DEBUG_KMS("mode: xres=%d, yres=%d, refresh=%d, clock=%d, intl=%d\n",
check_timing->xres, check_timing->yres,
check_timing->refresh, check_timing->pixclock,
(check_timing->vmode & FB_VMODE_INTERLACED) ?
true : false);
for (i = 0; i < ARRAY_SIZE(hdmiphy_v14_configs); i++)
if (hdmiphy_v14_configs[i].pixel_clock ==
check_timing->pixclock)
return 0;
return -EINVAL;
}
static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
{
struct hdmi_context *hdata = ctx;
int ret;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1064,10 +807,10 @@ static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
timing->yres, timing->refresh,
timing->vmode);
if (hdata->type == HDMI_TYPE13)
return hdmi_v13_check_timing(timing);
else
return hdmi_v14_check_timing(timing);
ret = hdmi_find_phy_conf(hdata, timing->pixclock);
if (ret < 0)
return ret;
return 0;
}
static void hdmi_set_acr(u32 freq, u8 *acr)
......@@ -1301,10 +1044,9 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
{
const struct hdmi_v13_preset_conf *conf =
hdmi_v13_confs[hdata->cur_conf].conf;
const struct hdmi_v13_core_regs *core = &conf->core;
const struct hdmi_v13_tg_regs *tg = &conf->tg;
const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
const struct hdmi_v13_core_regs *core =
&hdata->mode_conf.conf.v13_conf.core;
int tries;
/* setting core registers */
......@@ -1334,34 +1076,34 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
/* Timing generator registers */
hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
/* waiting for HDMIPHY's PLL to get to steady state */
for (tries = 100; tries; --tries) {
......@@ -1391,8 +1133,9 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
{
struct hdmi_core_regs *core = &hdata->mode_conf.core;
struct hdmi_tg_regs *tg = &hdata->mode_conf.tg;
const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
const struct hdmi_v14_core_regs *core =
&hdata->mode_conf.conf.v14_conf.core;
int tries;
/* setting core registers */
......@@ -1624,15 +1367,15 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
}
/* pixel clock */
if (hdata->type == HDMI_TYPE13) {
hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
} else {
i = hdmi_v14_find_phy_conf(hdata->mode_conf.pixel_clock);
i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
if (i < 0) {
DRM_ERROR("failed to find hdmiphy conf\n");
return;
}
if (hdata->type == HDMI_TYPE13) {
hdmiphy_data = hdmiphy_v13_configs[i].conf;
} else {
hdmiphy_data = hdmiphy_v14_configs[i].conf;
}
......@@ -1687,75 +1430,121 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
hdmi_regs_dump(hdata, "start");
}
static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
{
struct drm_display_mode *m;
struct hdmi_context *hdata = ctx;
int index;
int i;
BUG_ON(num_bytes > 4);
for (i = 0; i < num_bytes; i++)
reg_pair[i] = (value >> (8 * i)) & 0xff;
}
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
static void hdmi_v13_mode_set(struct hdmi_context *hdata,
struct drm_display_mode *m)
{
struct hdmi_v13_core_regs *core = &hdata->mode_conf.conf.v13_conf.core;
struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
unsigned int val;
drm_mode_set_crtcinfo(adjusted_mode, 0);
hdata->mode_conf.cea_video_id =
drm_match_cea_mode((struct drm_display_mode *)m);
hdata->mode_conf.pixel_clock = m->clock * 1000;
if (hdata->type == HDMI_TYPE13)
index = hdmi_v13_conf_index(adjusted_mode);
else
index = hdmi_v14_find_phy_conf(adjusted_mode->clock * 1000);
hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
/* just return if user desired mode exists. */
if (index >= 0)
return;
val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
hdmi_set_reg(core->vsync_pol, 1, val);
val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
hdmi_set_reg(core->int_pro_mode, 1, val);
val = (m->hsync_start - m->hdisplay - 2);
val |= ((m->hsync_end - m->hdisplay - 2) << 10);
val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
hdmi_set_reg(core->h_sync_gen, 3, val);
/*
* otherwise, find the most suitable mode among modes and change it
* to adjusted_mode.
* Quirk requirement for exynos HDMI IP design,
* 2 pixels less than the actual calculation for hsync_start
* and end.
*/
list_for_each_entry(m, &connector->modes, head) {
if (hdata->type == HDMI_TYPE13)
index = hdmi_v13_conf_index(m);
else
index = hdmi_v14_find_phy_conf(m->clock * 1000);
if (index >= 0) {
struct drm_mode_object base;
struct list_head head;
/* Following values & calculations differ for different type of modes */
if (m->flags & DRM_MODE_FLAG_INTERLACE) {
/* Interlaced Mode */
val = ((m->vsync_end - m->vdisplay) / 2);
val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
hdmi_set_reg(core->v_sync_gen1, 3, val);
DRM_INFO("desired mode doesn't exist so\n");
DRM_INFO("use the most suitable mode among modes.\n");
val = m->vtotal / 2;
val |= ((m->vtotal - m->vdisplay) / 2) << 11;
hdmi_set_reg(core->v_blank, 3, val);
DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
m->hdisplay, m->vdisplay, m->vrefresh);
val = (m->vtotal +
((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
val |= m->vtotal << 11;
hdmi_set_reg(core->v_blank_f, 3, val);
/* preserve display mode header while copying. */
head = adjusted_mode->head;
base = adjusted_mode->base;
memcpy(adjusted_mode, m, sizeof(*m));
adjusted_mode->head = head;
adjusted_mode->base = base;
break;
}
val = ((m->vtotal / 2) + 7);
val |= ((m->vtotal / 2) + 2) << 12;
hdmi_set_reg(core->v_sync_gen2, 3, val);
val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
val |= ((m->htotal / 2) +
(m->hsync_start - m->hdisplay)) << 12;
hdmi_set_reg(core->v_sync_gen3, 3, val);
hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
} else {
/* Progressive Mode */
val = m->vtotal;
val |= (m->vtotal - m->vdisplay) << 11;
hdmi_set_reg(core->v_blank, 3, val);
hdmi_set_reg(core->v_blank_f, 3, 0);
val = (m->vsync_end - m->vdisplay);
val |= ((m->vsync_start - m->vdisplay) << 12);
hdmi_set_reg(core->v_sync_gen1, 3, val);
hdmi_set_reg(core->v_sync_gen2, 3, 0x1001);/* Reset value */
hdmi_set_reg(core->v_sync_gen3, 3, 0x1001);/* Reset value */
hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
}
}
static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
{
int i;
BUG_ON(num_bytes > 4);
for (i = 0; i < num_bytes; i++)
reg_pair[i] = (value >> (8 * i)) & 0xff;
/* Timing generator registers */
hdmi_set_reg(tg->cmd, 1, 0x0);
hdmi_set_reg(tg->h_fsz, 2, m->htotal);
hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
hdmi_set_reg(tg->vsync, 2, 0x1);
hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->tg_3d, 1, 0x0); /* Not used */
}
static void hdmi_v14_mode_set(struct hdmi_context *hdata,
struct drm_display_mode *m)
{
struct hdmi_core_regs *core = &hdata->mode_conf.core;
struct hdmi_tg_regs *tg = &hdata->mode_conf.tg;
hdata->mode_conf.cea_video_id = drm_match_cea_mode(m);
struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
struct hdmi_v14_core_regs *core =
&hdata->mode_conf.conf.v14_conf.core;
hdata->mode_conf.cea_video_id =
drm_match_cea_mode((struct drm_display_mode *)m);
hdata->mode_conf.pixel_clock = m->clock * 1000;
hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
hdmi_set_reg(core->v_line, 2, m->vtotal);
hdmi_set_reg(core->h_line, 2, m->htotal);
......@@ -1852,22 +1641,20 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->tg_3d, 1, 0x0);
}
static void hdmi_mode_set(void *ctx, void *mode)
{
struct hdmi_context *hdata = ctx;
int conf_idx;
struct drm_display_mode *m = mode;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
DRM_DEBUG_KMS("[%s]: xres=%d, yres=%d, refresh=%d, intl=%s\n",
__func__, m->hdisplay, m->vdisplay,
m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
"INTERLACED" : "PROGERESSIVE");
if (hdata->type == HDMI_TYPE13) {
conf_idx = hdmi_v13_conf_index(mode);
if (conf_idx >= 0)
hdata->cur_conf = conf_idx;
else
DRM_DEBUG_KMS("not supported mode\n");
hdmi_v13_mode_set(hdata, mode);
} else {
hdmi_v14_mode_set(hdata, mode);
}
......@@ -1983,7 +1770,6 @@ static struct exynos_hdmi_ops hdmi_ops = {
.check_timing = hdmi_check_timing,
/* manager */
.mode_fixup = hdmi_mode_fixup,
.mode_set = hdmi_mode_set,
.get_max_resol = hdmi_get_max_resol,
.commit = hdmi_commit,
......@@ -2023,27 +1809,27 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
/* get clocks, power */
res->hdmi = devm_clk_get(dev, "hdmi");
if (IS_ERR_OR_NULL(res->hdmi)) {
if (IS_ERR(res->hdmi)) {
DRM_ERROR("failed to get clock 'hdmi'\n");
goto fail;
}
res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
if (IS_ERR(res->sclk_hdmi)) {
DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
goto fail;
}
res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
if (IS_ERR_OR_NULL(res->sclk_pixel)) {
if (IS_ERR(res->sclk_pixel)) {
DRM_ERROR("failed to get clock 'sclk_pixel'\n");
goto fail;
}
res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
if (IS_ERR(res->sclk_hdmiphy)) {
DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
goto fail;
}
res->hdmiphy = devm_clk_get(dev, "hdmiphy");
if (IS_ERR_OR_NULL(res->hdmiphy)) {
if (IS_ERR(res->hdmiphy)) {
DRM_ERROR("failed to get clock 'hdmiphy'\n");
goto fail;
}
......
......@@ -820,7 +820,6 @@ static void mixer_win_disable(void *ctx, int win)
static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
{
struct mixer_context *mixer_ctx = ctx;
u32 w, h;
w = timing->xres;
......@@ -831,9 +830,6 @@ static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
timing->refresh, (timing->vmode &
FB_VMODE_INTERLACED) ? true : false);
if (mixer_ctx->mxr_ver == MXR_VER_0_0_0_16)
return 0;
if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
(w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
......@@ -1047,13 +1043,13 @@ static int mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
spin_lock_init(&mixer_res->reg_slock);
mixer_res->mixer = devm_clk_get(dev, "mixer");
if (IS_ERR_OR_NULL(mixer_res->mixer)) {
if (IS_ERR(mixer_res->mixer)) {
dev_err(dev, "failed to get clock 'mixer'\n");
return -ENODEV;
}
mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
if (IS_ERR(mixer_res->sclk_hdmi)) {
dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
return -ENODEV;
}
......@@ -1096,17 +1092,17 @@ static int vp_resources_init(struct exynos_drm_hdmi_context *ctx,
struct resource *res;
mixer_res->vp = devm_clk_get(dev, "vp");
if (IS_ERR_OR_NULL(mixer_res->vp)) {
if (IS_ERR(mixer_res->vp)) {
dev_err(dev, "failed to get clock 'vp'\n");
return -ENODEV;
}
mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
if (IS_ERR(mixer_res->sclk_mixer)) {
dev_err(dev, "failed to get clock 'sclk_mixer'\n");
return -ENODEV;
}
mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
if (IS_ERR(mixer_res->sclk_dac)) {
dev_err(dev, "failed to get clock 'sclk_dac'\n");
return -ENODEV;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment