aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c77
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h6
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c276
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c288
4 files changed, 341 insertions, 306 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index 3424463676e0..5d9d2c2f8f3f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -37,6 +37,8 @@ struct drm_hdmi_context {
37 struct exynos_drm_subdrv subdrv; 37 struct exynos_drm_subdrv subdrv;
38 struct exynos_drm_hdmi_context *hdmi_ctx; 38 struct exynos_drm_hdmi_context *hdmi_ctx;
39 struct exynos_drm_hdmi_context *mixer_ctx; 39 struct exynos_drm_hdmi_context *mixer_ctx;
40
41 bool enabled[MIXER_WIN_NR];
40}; 42};
41 43
42void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) 44void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
@@ -189,23 +191,34 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
189 191
190 DRM_DEBUG_KMS("%s\n", __FILE__); 192 DRM_DEBUG_KMS("%s\n", __FILE__);
191 193
192 switch (mode) { 194 if (mixer_ops && mixer_ops->dpms)
193 case DRM_MODE_DPMS_ON: 195 mixer_ops->dpms(ctx->mixer_ctx->ctx, mode);
194 break; 196
195 case DRM_MODE_DPMS_STANDBY: 197 if (hdmi_ops && hdmi_ops->dpms)
196 case DRM_MODE_DPMS_SUSPEND: 198 hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode);
197 case DRM_MODE_DPMS_OFF: 199}
198 if (hdmi_ops && hdmi_ops->disable) 200
199 hdmi_ops->disable(ctx->hdmi_ctx->ctx); 201static void drm_hdmi_apply(struct device *subdrv_dev)
200 break; 202{
201 default: 203 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
202 DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); 204 int i;
203 break; 205
206 DRM_DEBUG_KMS("%s\n", __FILE__);
207
208 for (i = 0; i < MIXER_WIN_NR; i++) {
209 if (!ctx->enabled[i])
210 continue;
211 if (mixer_ops && mixer_ops->win_commit)
212 mixer_ops->win_commit(ctx->mixer_ctx->ctx, i);
204 } 213 }
214
215 if (hdmi_ops && hdmi_ops->commit)
216 hdmi_ops->commit(ctx->hdmi_ctx->ctx);
205} 217}
206 218
207static struct exynos_drm_manager_ops drm_hdmi_manager_ops = { 219static struct exynos_drm_manager_ops drm_hdmi_manager_ops = {
208 .dpms = drm_hdmi_dpms, 220 .dpms = drm_hdmi_dpms,
221 .apply = drm_hdmi_apply,
209 .enable_vblank = drm_hdmi_enable_vblank, 222 .enable_vblank = drm_hdmi_enable_vblank,
210 .disable_vblank = drm_hdmi_disable_vblank, 223 .disable_vblank = drm_hdmi_disable_vblank,
211 .mode_fixup = drm_hdmi_mode_fixup, 224 .mode_fixup = drm_hdmi_mode_fixup,
@@ -228,21 +241,37 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
228static void drm_mixer_commit(struct device *subdrv_dev, int zpos) 241static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
229{ 242{
230 struct drm_hdmi_context *ctx = to_context(subdrv_dev); 243 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
244 int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
231 245
232 DRM_DEBUG_KMS("%s\n", __FILE__); 246 DRM_DEBUG_KMS("%s\n", __FILE__);
233 247
248 if (win < 0 || win > MIXER_WIN_NR) {
249 DRM_ERROR("mixer window[%d] is wrong\n", win);
250 return;
251 }
252
234 if (mixer_ops && mixer_ops->win_commit) 253 if (mixer_ops && mixer_ops->win_commit)
235 mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); 254 mixer_ops->win_commit(ctx->mixer_ctx->ctx, win);
255
256 ctx->enabled[win] = true;
236} 257}
237 258
238static void drm_mixer_disable(struct device *subdrv_dev, int zpos) 259static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
239{ 260{
240 struct drm_hdmi_context *ctx = to_context(subdrv_dev); 261 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
262 int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
241 263
242 DRM_DEBUG_KMS("%s\n", __FILE__); 264 DRM_DEBUG_KMS("%s\n", __FILE__);
243 265
266 if (win < 0 || win > MIXER_WIN_NR) {
267 DRM_ERROR("mixer window[%d] is wrong\n", win);
268 return;
269 }
270
244 if (mixer_ops && mixer_ops->win_disable) 271 if (mixer_ops && mixer_ops->win_disable)
245 mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); 272 mixer_ops->win_disable(ctx->mixer_ctx->ctx, win);
273
274 ctx->enabled[win] = false;
246} 275}
247 276
248static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { 277static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
@@ -335,25 +364,6 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
335 return 0; 364 return 0;
336} 365}
337 366
338static int hdmi_runtime_suspend(struct device *dev)
339{
340 DRM_DEBUG_KMS("%s\n", __FILE__);
341
342 return 0;
343}
344
345static int hdmi_runtime_resume(struct device *dev)
346{
347 DRM_DEBUG_KMS("%s\n", __FILE__);
348
349 return 0;
350}
351
352static const struct dev_pm_ops hdmi_pm_ops = {
353 .runtime_suspend = hdmi_runtime_suspend,
354 .runtime_resume = hdmi_runtime_resume,
355};
356
357static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) 367static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)
358{ 368{
359 struct drm_hdmi_context *ctx = platform_get_drvdata(pdev); 369 struct drm_hdmi_context *ctx = platform_get_drvdata(pdev);
@@ -372,6 +382,5 @@ struct platform_driver exynos_drm_common_hdmi_driver = {
372 .driver = { 382 .driver = {
373 .name = "exynos-drm-hdmi", 383 .name = "exynos-drm-hdmi",
374 .owner = THIS_MODULE, 384 .owner = THIS_MODULE,
375 .pm = &hdmi_pm_ops,
376 }, 385 },
377}; 386};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index f3ae192c8dcf..bd8126996e52 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -26,6 +26,9 @@
26#ifndef _EXYNOS_DRM_HDMI_H_ 26#ifndef _EXYNOS_DRM_HDMI_H_
27#define _EXYNOS_DRM_HDMI_H_ 27#define _EXYNOS_DRM_HDMI_H_
28 28
29#define MIXER_WIN_NR 3
30#define MIXER_DEFAULT_WIN 0
31
29/* 32/*
30 * exynos hdmi common context structure. 33 * exynos hdmi common context structure.
31 * 34 *
@@ -54,13 +57,14 @@ struct exynos_hdmi_ops {
54 void (*get_max_resol)(void *ctx, unsigned int *width, 57 void (*get_max_resol)(void *ctx, unsigned int *width,
55 unsigned int *height); 58 unsigned int *height);
56 void (*commit)(void *ctx); 59 void (*commit)(void *ctx);
57 void (*disable)(void *ctx); 60 void (*dpms)(void *ctx, int mode);
58}; 61};
59 62
60struct exynos_mixer_ops { 63struct exynos_mixer_ops {
61 /* manager */ 64 /* manager */
62 int (*enable_vblank)(void *ctx, int pipe); 65 int (*enable_vblank)(void *ctx, int pipe);
63 void (*disable_vblank)(void *ctx); 66 void (*disable_vblank)(void *ctx);
67 void (*dpms)(void *ctx, int mode);
64 68
65 /* overlay */ 69 /* overlay */
66 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); 70 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 5b04af145fa7..9212d7d53f3a 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -57,13 +57,15 @@ struct hdmi_resources {
57struct hdmi_context { 57struct hdmi_context {
58 struct device *dev; 58 struct device *dev;
59 struct drm_device *drm_dev; 59 struct drm_device *drm_dev;
60 bool hpd_handle; 60 bool hpd;
61 bool enabled; 61 bool powered;
62 bool is_v13; 62 bool is_v13;
63 struct mutex hdmi_mutex;
63 64
64 struct resource *regs_res; 65 struct resource *regs_res;
65 void __iomem *regs; 66 void __iomem *regs;
66 unsigned int irq; 67 unsigned int external_irq;
68 unsigned int internal_irq;
67 69
68 struct i2c_client *ddc_port; 70 struct i2c_client *ddc_port;
69 struct i2c_client *hdmiphy_port; 71 struct i2c_client *hdmiphy_port;
@@ -1192,12 +1194,8 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
1192static bool hdmi_is_connected(void *ctx) 1194static bool hdmi_is_connected(void *ctx)
1193{ 1195{
1194 struct hdmi_context *hdata = ctx; 1196 struct hdmi_context *hdata = ctx;
1195 u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
1196 1197
1197 if (val) 1198 return hdata->hpd;
1198 return true;
1199
1200 return false;
1201} 1199}
1202 1200
1203static int hdmi_get_edid(void *ctx, struct drm_connector *connector, 1201static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
@@ -1287,28 +1285,6 @@ static int hdmi_check_timing(void *ctx, void *timing)
1287 return hdmi_v14_check_timing(check_timing); 1285 return hdmi_v14_check_timing(check_timing);
1288} 1286}
1289 1287
1290static int hdmi_display_power_on(void *ctx, int mode)
1291{
1292 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1293
1294 switch (mode) {
1295 case DRM_MODE_DPMS_ON:
1296 DRM_DEBUG_KMS("hdmi [on]\n");
1297 break;
1298 case DRM_MODE_DPMS_STANDBY:
1299 break;
1300 case DRM_MODE_DPMS_SUSPEND:
1301 break;
1302 case DRM_MODE_DPMS_OFF:
1303 DRM_DEBUG_KMS("hdmi [off]\n");
1304 break;
1305 default:
1306 break;
1307 }
1308
1309 return 0;
1310}
1311
1312static void hdmi_set_acr(u32 freq, u8 *acr) 1288static void hdmi_set_acr(u32 freq, u8 *acr)
1313{ 1289{
1314 u32 n, cts; 1290 u32 n, cts;
@@ -1476,9 +1452,6 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
1476{ 1452{
1477 u32 reg; 1453 u32 reg;
1478 1454
1479 /* disable hpd handle for drm */
1480 hdata->hpd_handle = false;
1481
1482 if (hdata->is_v13) 1455 if (hdata->is_v13)
1483 reg = HDMI_V13_CORE_RSTOUT; 1456 reg = HDMI_V13_CORE_RSTOUT;
1484 else 1457 else
@@ -1489,16 +1462,10 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
1489 mdelay(10); 1462 mdelay(10);
1490 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); 1463 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1491 mdelay(10); 1464 mdelay(10);
1492
1493 /* enable hpd handle for drm */
1494 hdata->hpd_handle = true;
1495} 1465}
1496 1466
1497static void hdmi_conf_init(struct hdmi_context *hdata) 1467static void hdmi_conf_init(struct hdmi_context *hdata)
1498{ 1468{
1499 /* disable hpd handle for drm */
1500 hdata->hpd_handle = false;
1501
1502 /* enable HPD interrupts */ 1469 /* enable HPD interrupts */
1503 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | 1470 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1504 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); 1471 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
@@ -1533,9 +1500,6 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
1533 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5); 1500 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1534 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); 1501 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1535 } 1502 }
1536
1537 /* enable hpd handle for drm */
1538 hdata->hpd_handle = true;
1539} 1503}
1540 1504
1541static void hdmi_v13_timing_apply(struct hdmi_context *hdata) 1505static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
@@ -1888,8 +1852,11 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
1888 hdmiphy_conf_reset(hdata); 1852 hdmiphy_conf_reset(hdata);
1889 hdmiphy_conf_apply(hdata); 1853 hdmiphy_conf_apply(hdata);
1890 1854
1855 mutex_lock(&hdata->hdmi_mutex);
1891 hdmi_conf_reset(hdata); 1856 hdmi_conf_reset(hdata);
1892 hdmi_conf_init(hdata); 1857 hdmi_conf_init(hdata);
1858 mutex_unlock(&hdata->hdmi_mutex);
1859
1893 hdmi_audio_init(hdata); 1860 hdmi_audio_init(hdata);
1894 1861
1895 /* setting core registers */ 1862 /* setting core registers */
@@ -1969,20 +1936,86 @@ static void hdmi_commit(void *ctx)
1969 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1936 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1970 1937
1971 hdmi_conf_apply(hdata); 1938 hdmi_conf_apply(hdata);
1939}
1940
1941static void hdmi_poweron(struct hdmi_context *hdata)
1942{
1943 struct hdmi_resources *res = &hdata->res;
1944
1945 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1946
1947 mutex_lock(&hdata->hdmi_mutex);
1948 if (hdata->powered) {
1949 mutex_unlock(&hdata->hdmi_mutex);
1950 return;
1951 }
1972 1952
1973 hdata->enabled = true; 1953 hdata->powered = true;
1954
1955 if (hdata->cfg_hpd)
1956 hdata->cfg_hpd(true);
1957 mutex_unlock(&hdata->hdmi_mutex);
1958
1959 pm_runtime_get_sync(hdata->dev);
1960
1961 regulator_bulk_enable(res->regul_count, res->regul_bulk);
1962 clk_enable(res->hdmiphy);
1963 clk_enable(res->hdmi);
1964 clk_enable(res->sclk_hdmi);
1965}
1966
1967static void hdmi_poweroff(struct hdmi_context *hdata)
1968{
1969 struct hdmi_resources *res = &hdata->res;
1970
1971 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1972
1973 mutex_lock(&hdata->hdmi_mutex);
1974 if (!hdata->powered)
1975 goto out;
1976 mutex_unlock(&hdata->hdmi_mutex);
1977
1978 /*
1979 * The TV power domain needs any condition of hdmiphy to turn off and
1980 * its reset state seems to meet the condition.
1981 */
1982 hdmiphy_conf_reset(hdata);
1983
1984 clk_disable(res->sclk_hdmi);
1985 clk_disable(res->hdmi);
1986 clk_disable(res->hdmiphy);
1987 regulator_bulk_disable(res->regul_count, res->regul_bulk);
1988
1989 pm_runtime_put_sync(hdata->dev);
1990
1991 mutex_lock(&hdata->hdmi_mutex);
1992 if (hdata->cfg_hpd)
1993 hdata->cfg_hpd(false);
1994
1995 hdata->powered = false;
1996
1997out:
1998 mutex_unlock(&hdata->hdmi_mutex);
1974} 1999}
1975 2000
1976static void hdmi_disable(void *ctx) 2001static void hdmi_dpms(void *ctx, int mode)
1977{ 2002{
1978 struct hdmi_context *hdata = ctx; 2003 struct hdmi_context *hdata = ctx;
1979 2004
1980 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2005 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1981 2006
1982 if (hdata->enabled) { 2007 switch (mode) {
1983 hdmi_audio_control(hdata, false); 2008 case DRM_MODE_DPMS_ON:
1984 hdmiphy_conf_reset(hdata); 2009 hdmi_poweron(hdata);
1985 hdmi_conf_reset(hdata); 2010 break;
2011 case DRM_MODE_DPMS_STANDBY:
2012 case DRM_MODE_DPMS_SUSPEND:
2013 case DRM_MODE_DPMS_OFF:
2014 hdmi_poweroff(hdata);
2015 break;
2016 default:
2017 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2018 break;
1986 } 2019 }
1987} 2020}
1988 2021
@@ -1991,17 +2024,35 @@ static struct exynos_hdmi_ops hdmi_ops = {
1991 .is_connected = hdmi_is_connected, 2024 .is_connected = hdmi_is_connected,
1992 .get_edid = hdmi_get_edid, 2025 .get_edid = hdmi_get_edid,
1993 .check_timing = hdmi_check_timing, 2026 .check_timing = hdmi_check_timing,
1994 .power_on = hdmi_display_power_on,
1995 2027
1996 /* manager */ 2028 /* manager */
1997 .mode_fixup = hdmi_mode_fixup, 2029 .mode_fixup = hdmi_mode_fixup,
1998 .mode_set = hdmi_mode_set, 2030 .mode_set = hdmi_mode_set,
1999 .get_max_resol = hdmi_get_max_resol, 2031 .get_max_resol = hdmi_get_max_resol,
2000 .commit = hdmi_commit, 2032 .commit = hdmi_commit,
2001 .disable = hdmi_disable, 2033 .dpms = hdmi_dpms,
2002}; 2034};
2003 2035
2004static irqreturn_t hdmi_irq_thread(int irq, void *arg) 2036static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2037{
2038 struct exynos_drm_hdmi_context *ctx = arg;
2039 struct hdmi_context *hdata = ctx->ctx;
2040
2041 if (!hdata->get_hpd)
2042 goto out;
2043
2044 mutex_lock(&hdata->hdmi_mutex);
2045 hdata->hpd = hdata->get_hpd();
2046 mutex_unlock(&hdata->hdmi_mutex);
2047
2048 if (ctx->drm_dev)
2049 drm_helper_hpd_irq_event(ctx->drm_dev);
2050
2051out:
2052 return IRQ_HANDLED;
2053}
2054
2055static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2005{ 2056{
2006 struct exynos_drm_hdmi_context *ctx = arg; 2057 struct exynos_drm_hdmi_context *ctx = arg;
2007 struct hdmi_context *hdata = ctx->ctx; 2058 struct hdmi_context *hdata = ctx->ctx;
@@ -2010,19 +2061,28 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
2010 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); 2061 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2011 /* clearing flags for HPD plug/unplug */ 2062 /* clearing flags for HPD plug/unplug */
2012 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) { 2063 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2013 DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata->hpd_handle); 2064 DRM_DEBUG_KMS("unplugged\n");
2014 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, 2065 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2015 HDMI_INTC_FLAG_HPD_UNPLUG); 2066 HDMI_INTC_FLAG_HPD_UNPLUG);
2016 } 2067 }
2017 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) { 2068 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2018 DRM_DEBUG_KMS("plugged, handling:%d\n", hdata->hpd_handle); 2069 DRM_DEBUG_KMS("plugged\n");
2019 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, 2070 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2020 HDMI_INTC_FLAG_HPD_PLUG); 2071 HDMI_INTC_FLAG_HPD_PLUG);
2021 } 2072 }
2022 2073
2023 if (ctx->drm_dev && hdata->hpd_handle) 2074 mutex_lock(&hdata->hdmi_mutex);
2075 hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
2076 if (hdata->powered && hdata->hpd) {
2077 mutex_unlock(&hdata->hdmi_mutex);
2078 goto out;
2079 }
2080 mutex_unlock(&hdata->hdmi_mutex);
2081
2082 if (ctx->drm_dev)
2024 drm_helper_hpd_irq_event(ctx->drm_dev); 2083 drm_helper_hpd_irq_event(ctx->drm_dev);
2025 2084
2085out:
2026 return IRQ_HANDLED; 2086 return IRQ_HANDLED;
2027} 2087}
2028 2088
@@ -2116,68 +2176,6 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2116 return 0; 2176 return 0;
2117} 2177}
2118 2178
2119static void hdmi_resource_poweron(struct hdmi_context *hdata)
2120{
2121 struct hdmi_resources *res = &hdata->res;
2122
2123 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2124
2125 /* turn HDMI power on */
2126 regulator_bulk_enable(res->regul_count, res->regul_bulk);
2127 /* power-on hdmi physical interface */
2128 clk_enable(res->hdmiphy);
2129 /* turn clocks on */
2130 clk_enable(res->hdmi);
2131 clk_enable(res->sclk_hdmi);
2132
2133 hdmiphy_conf_reset(hdata);
2134 hdmi_conf_reset(hdata);
2135 hdmi_conf_init(hdata);
2136 hdmi_audio_init(hdata);
2137}
2138
2139static void hdmi_resource_poweroff(struct hdmi_context *hdata)
2140{
2141 struct hdmi_resources *res = &hdata->res;
2142
2143 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2144
2145 /* turn clocks off */
2146 clk_disable(res->sclk_hdmi);
2147 clk_disable(res->hdmi);
2148 /* power-off hdmiphy */
2149 clk_disable(res->hdmiphy);
2150 /* turn HDMI power off */
2151 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2152}
2153
2154static int hdmi_runtime_suspend(struct device *dev)
2155{
2156 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2157
2158 DRM_DEBUG_KMS("%s\n", __func__);
2159
2160 hdmi_resource_poweroff(ctx->ctx);
2161
2162 return 0;
2163}
2164
2165static int hdmi_runtime_resume(struct device *dev)
2166{
2167 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2168
2169 DRM_DEBUG_KMS("%s\n", __func__);
2170
2171 hdmi_resource_poweron(ctx->ctx);
2172
2173 return 0;
2174}
2175
2176static const struct dev_pm_ops hdmi_pm_ops = {
2177 .runtime_suspend = hdmi_runtime_suspend,
2178 .runtime_resume = hdmi_runtime_resume,
2179};
2180
2181static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy; 2179static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2182 2180
2183void hdmi_attach_ddc_client(struct i2c_client *ddc) 2181void hdmi_attach_ddc_client(struct i2c_client *ddc)
@@ -2222,6 +2220,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2222 return -ENOMEM; 2220 return -ENOMEM;
2223 } 2221 }
2224 2222
2223 mutex_init(&hdata->hdmi_mutex);
2224
2225 drm_hdmi_ctx->ctx = (void *)hdata; 2225 drm_hdmi_ctx->ctx = (void *)hdata;
2226 hdata->parent_ctx = (void *)drm_hdmi_ctx; 2226 hdata->parent_ctx = (void *)drm_hdmi_ctx;
2227 2227
@@ -2278,28 +2278,49 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2278 2278
2279 hdata->hdmiphy_port = hdmi_hdmiphy; 2279 hdata->hdmiphy_port = hdmi_hdmiphy;
2280 2280
2281 hdata->irq = platform_get_irq_byname(pdev, "internal_irq"); 2281 hdata->external_irq = platform_get_irq_byname(pdev, "external_irq");
2282 if (hdata->irq < 0) { 2282 if (hdata->external_irq < 0) {
2283 DRM_ERROR("failed to get platform irq\n"); 2283 DRM_ERROR("failed to get platform irq\n");
2284 ret = hdata->irq; 2284 ret = hdata->external_irq;
2285 goto err_hdmiphy; 2285 goto err_hdmiphy;
2286 } 2286 }
2287 2287
2288 /* register hpd interrupt */ 2288 hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq");
2289 ret = request_threaded_irq(hdata->irq, NULL, hdmi_irq_thread, 2289 if (hdata->internal_irq < 0) {
2290 IRQF_ONESHOT, "drm_hdmi", drm_hdmi_ctx); 2290 DRM_ERROR("failed to get platform internal irq\n");
2291 ret = hdata->internal_irq;
2292 goto err_hdmiphy;
2293 }
2294
2295 ret = request_threaded_irq(hdata->external_irq, NULL,
2296 hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2297 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2298 "hdmi_external", drm_hdmi_ctx);
2291 if (ret) { 2299 if (ret) {
2292 DRM_ERROR("request interrupt failed.\n"); 2300 DRM_ERROR("failed to register hdmi internal interrupt\n");
2293 goto err_hdmiphy; 2301 goto err_hdmiphy;
2294 } 2302 }
2295 2303
2304 if (hdata->cfg_hpd)
2305 hdata->cfg_hpd(false);
2306
2307 ret = request_threaded_irq(hdata->internal_irq, NULL,
2308 hdmi_internal_irq_thread, IRQF_ONESHOT,
2309 "hdmi_internal", drm_hdmi_ctx);
2310 if (ret) {
2311 DRM_ERROR("failed to register hdmi internal interrupt\n");
2312 goto err_free_irq;
2313 }
2314
2296 /* register specific callbacks to common hdmi. */ 2315 /* register specific callbacks to common hdmi. */
2297 exynos_hdmi_ops_register(&hdmi_ops); 2316 exynos_hdmi_ops_register(&hdmi_ops);
2298 2317
2299 hdmi_resource_poweron(hdata); 2318 pm_runtime_enable(dev);
2300 2319
2301 return 0; 2320 return 0;
2302 2321
2322err_free_irq:
2323 free_irq(hdata->external_irq, drm_hdmi_ctx);
2303err_hdmiphy: 2324err_hdmiphy:
2304 i2c_del_driver(&hdmiphy_driver); 2325 i2c_del_driver(&hdmiphy_driver);
2305err_ddc: 2326err_ddc:
@@ -2319,15 +2340,15 @@ err_data:
2319 2340
2320static int __devexit hdmi_remove(struct platform_device *pdev) 2341static int __devexit hdmi_remove(struct platform_device *pdev)
2321{ 2342{
2343 struct device *dev = &pdev->dev;
2322 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); 2344 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2323 struct hdmi_context *hdata = ctx->ctx; 2345 struct hdmi_context *hdata = ctx->ctx;
2324 2346
2325 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2347 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2326 2348
2327 hdmi_resource_poweroff(hdata); 2349 pm_runtime_disable(dev);
2328 2350
2329 disable_irq(hdata->irq); 2351 free_irq(hdata->internal_irq, hdata);
2330 free_irq(hdata->irq, hdata);
2331 2352
2332 hdmi_resources_cleanup(hdata); 2353 hdmi_resources_cleanup(hdata);
2333 2354
@@ -2352,6 +2373,5 @@ struct platform_driver hdmi_driver = {
2352 .driver = { 2373 .driver = {
2353 .name = "exynos4-hdmi", 2374 .name = "exynos4-hdmi",
2354 .owner = THIS_MODULE, 2375 .owner = THIS_MODULE,
2355 .pm = &hdmi_pm_ops,
2356 }, 2376 },
2357}; 2377};
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index e15438c01129..a29a9a8b2312 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -37,9 +37,6 @@
37#include "exynos_drm_drv.h" 37#include "exynos_drm_drv.h"
38#include "exynos_drm_hdmi.h" 38#include "exynos_drm_hdmi.h"
39 39
40#define MIXER_WIN_NR 3
41#define MIXER_DEFAULT_WIN 0
42
43#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) 40#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
44 41
45struct hdmi_win_data { 42struct hdmi_win_data {
@@ -63,7 +60,6 @@ struct hdmi_win_data {
63}; 60};
64 61
65struct mixer_resources { 62struct mixer_resources {
66 struct device *dev;
67 int irq; 63 int irq;
68 void __iomem *mixer_regs; 64 void __iomem *mixer_regs;
69 void __iomem *vp_regs; 65 void __iomem *vp_regs;
@@ -76,10 +72,13 @@ struct mixer_resources {
76}; 72};
77 73
78struct mixer_context { 74struct mixer_context {
79 unsigned int irq; 75 struct device *dev;
80 int pipe; 76 int pipe;
81 bool interlace; 77 bool interlace;
78 bool powered;
79 u32 int_en;
82 80
81 struct mutex mixer_mutex;
83 struct mixer_resources mixer_res; 82 struct mixer_resources mixer_res;
84 struct hdmi_win_data win_data[MIXER_WIN_NR]; 83 struct hdmi_win_data win_data[MIXER_WIN_NR];
85}; 84};
@@ -591,6 +590,116 @@ static void vp_win_reset(struct mixer_context *ctx)
591 WARN(tries == 0, "failed to reset Video Processor\n"); 590 WARN(tries == 0, "failed to reset Video Processor\n");
592} 591}
593 592
593static void mixer_win_reset(struct mixer_context *ctx)
594{
595 struct mixer_resources *res = &ctx->mixer_res;
596 unsigned long flags;
597 u32 val; /* value stored to register */
598
599 spin_lock_irqsave(&res->reg_slock, flags);
600 mixer_vsync_set_update(ctx, false);
601
602 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
603
604 /* set output in RGB888 mode */
605 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
606
607 /* 16 beat burst in DMA */
608 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
609 MXR_STATUS_BURST_MASK);
610
611 /* setting default layer priority: layer1 > layer0 > video
612 * because typical usage scenario would be
613 * layer1 - OSD
614 * layer0 - framebuffer
615 * video - video overlay
616 */
617 val = MXR_LAYER_CFG_GRP1_VAL(3);
618 val |= MXR_LAYER_CFG_GRP0_VAL(2);
619 val |= MXR_LAYER_CFG_VP_VAL(1);
620 mixer_reg_write(res, MXR_LAYER_CFG, val);
621
622 /* setting background color */
623 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
624 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
625 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
626
627 /* setting graphical layers */
628
629 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
630 val |= MXR_GRP_CFG_WIN_BLEND_EN;
631 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
632
633 /* the same configuration for both layers */
634 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
635
636 val |= MXR_GRP_CFG_BLEND_PRE_MUL;
637 val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
638 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
639
640 /* configuration of Video Processor Registers */
641 vp_win_reset(ctx);
642 vp_default_filter(res);
643
644 /* disable all layers */
645 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
646 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
647 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
648
649 mixer_vsync_set_update(ctx, true);
650 spin_unlock_irqrestore(&res->reg_slock, flags);
651}
652
653static void mixer_poweron(struct mixer_context *ctx)
654{
655 struct mixer_resources *res = &ctx->mixer_res;
656
657 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
658
659 mutex_lock(&ctx->mixer_mutex);
660 if (ctx->powered) {
661 mutex_unlock(&ctx->mixer_mutex);
662 return;
663 }
664 ctx->powered = true;
665 mutex_unlock(&ctx->mixer_mutex);
666
667 pm_runtime_get_sync(ctx->dev);
668
669 clk_enable(res->mixer);
670 clk_enable(res->vp);
671 clk_enable(res->sclk_mixer);
672
673 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
674 mixer_win_reset(ctx);
675}
676
677static void mixer_poweroff(struct mixer_context *ctx)
678{
679 struct mixer_resources *res = &ctx->mixer_res;
680
681 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
682
683 mutex_lock(&ctx->mixer_mutex);
684 if (!ctx->powered)
685 goto out;
686 mutex_unlock(&ctx->mixer_mutex);
687
688 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
689
690 clk_disable(res->mixer);
691 clk_disable(res->vp);
692 clk_disable(res->sclk_mixer);
693
694 pm_runtime_put_sync(ctx->dev);
695
696 mutex_lock(&ctx->mixer_mutex);
697 ctx->powered = false;
698
699out:
700 mutex_unlock(&ctx->mixer_mutex);
701}
702
594static int mixer_enable_vblank(void *ctx, int pipe) 703static int mixer_enable_vblank(void *ctx, int pipe)
595{ 704{
596 struct mixer_context *mixer_ctx = ctx; 705 struct mixer_context *mixer_ctx = ctx;
@@ -618,6 +727,27 @@ static void mixer_disable_vblank(void *ctx)
618 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); 727 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
619} 728}
620 729
730static void mixer_dpms(void *ctx, int mode)
731{
732 struct mixer_context *mixer_ctx = ctx;
733
734 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
735
736 switch (mode) {
737 case DRM_MODE_DPMS_ON:
738 mixer_poweron(mixer_ctx);
739 break;
740 case DRM_MODE_DPMS_STANDBY:
741 case DRM_MODE_DPMS_SUSPEND:
742 case DRM_MODE_DPMS_OFF:
743 mixer_poweroff(mixer_ctx);
744 break;
745 default:
746 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
747 break;
748 }
749}
750
621static void mixer_win_mode_set(void *ctx, 751static void mixer_win_mode_set(void *ctx,
622 struct exynos_drm_overlay *overlay) 752 struct exynos_drm_overlay *overlay)
623{ 753{
@@ -643,7 +773,7 @@ static void mixer_win_mode_set(void *ctx,
643 win = MIXER_DEFAULT_WIN; 773 win = MIXER_DEFAULT_WIN;
644 774
645 if (win < 0 || win > MIXER_WIN_NR) { 775 if (win < 0 || win > MIXER_WIN_NR) {
646 DRM_ERROR("overlay plane[%d] is wrong\n", win); 776 DRM_ERROR("mixer window[%d] is wrong\n", win);
647 return; 777 return;
648 } 778 }
649 779
@@ -672,44 +802,26 @@ static void mixer_win_mode_set(void *ctx,
672 win_data->scan_flags = overlay->scan_flag; 802 win_data->scan_flags = overlay->scan_flag;
673} 803}
674 804
675static void mixer_win_commit(void *ctx, int zpos) 805static void mixer_win_commit(void *ctx, int win)
676{ 806{
677 struct mixer_context *mixer_ctx = ctx; 807 struct mixer_context *mixer_ctx = ctx;
678 int win = zpos;
679 808
680 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); 809 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
681 810
682 if (win == DEFAULT_ZPOS)
683 win = MIXER_DEFAULT_WIN;
684
685 if (win < 0 || win > MIXER_WIN_NR) {
686 DRM_ERROR("overlay plane[%d] is wrong\n", win);
687 return;
688 }
689
690 if (win > 1) 811 if (win > 1)
691 vp_video_buffer(mixer_ctx, win); 812 vp_video_buffer(mixer_ctx, win);
692 else 813 else
693 mixer_graph_buffer(mixer_ctx, win); 814 mixer_graph_buffer(mixer_ctx, win);
694} 815}
695 816
696static void mixer_win_disable(void *ctx, int zpos) 817static void mixer_win_disable(void *ctx, int win)
697{ 818{
698 struct mixer_context *mixer_ctx = ctx; 819 struct mixer_context *mixer_ctx = ctx;
699 struct mixer_resources *res = &mixer_ctx->mixer_res; 820 struct mixer_resources *res = &mixer_ctx->mixer_res;
700 unsigned long flags; 821 unsigned long flags;
701 int win = zpos;
702 822
703 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); 823 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
704 824
705 if (win == DEFAULT_ZPOS)
706 win = MIXER_DEFAULT_WIN;
707
708 if (win < 0 || win > MIXER_WIN_NR) {
709 DRM_ERROR("overlay plane[%d] is wrong\n", win);
710 return;
711 }
712
713 spin_lock_irqsave(&res->reg_slock, flags); 825 spin_lock_irqsave(&res->reg_slock, flags);
714 mixer_vsync_set_update(mixer_ctx, false); 826 mixer_vsync_set_update(mixer_ctx, false);
715 827
@@ -723,6 +835,7 @@ static struct exynos_mixer_ops mixer_ops = {
723 /* manager */ 835 /* manager */
724 .enable_vblank = mixer_enable_vblank, 836 .enable_vblank = mixer_enable_vblank,
725 .disable_vblank = mixer_disable_vblank, 837 .disable_vblank = mixer_disable_vblank,
838 .dpms = mixer_dpms,
726 839
727 /* overlay */ 840 /* overlay */
728 .win_mode_set = mixer_win_mode_set, 841 .win_mode_set = mixer_win_mode_set,
@@ -811,117 +924,6 @@ out:
811 return IRQ_HANDLED; 924 return IRQ_HANDLED;
812} 925}
813 926
814static void mixer_win_reset(struct mixer_context *ctx)
815{
816 struct mixer_resources *res = &ctx->mixer_res;
817 unsigned long flags;
818 u32 val; /* value stored to register */
819
820 spin_lock_irqsave(&res->reg_slock, flags);
821 mixer_vsync_set_update(ctx, false);
822
823 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
824
825 /* set output in RGB888 mode */
826 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
827
828 /* 16 beat burst in DMA */
829 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
830 MXR_STATUS_BURST_MASK);
831
832 /* setting default layer priority: layer1 > layer0 > video
833 * because typical usage scenario would be
834 * layer1 - OSD
835 * layer0 - framebuffer
836 * video - video overlay
837 */
838 val = MXR_LAYER_CFG_GRP1_VAL(3);
839 val |= MXR_LAYER_CFG_GRP0_VAL(2);
840 val |= MXR_LAYER_CFG_VP_VAL(1);
841 mixer_reg_write(res, MXR_LAYER_CFG, val);
842
843 /* setting background color */
844 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
845 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
846 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
847
848 /* setting graphical layers */
849
850 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
851 val |= MXR_GRP_CFG_WIN_BLEND_EN;
852 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
853
854 /* the same configuration for both layers */
855 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
856
857 val |= MXR_GRP_CFG_BLEND_PRE_MUL;
858 val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
859 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
860
861 /* configuration of Video Processor Registers */
862 vp_win_reset(ctx);
863 vp_default_filter(res);
864
865 /* disable all layers */
866 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
867 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
868 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
869
870 mixer_vsync_set_update(ctx, true);
871 spin_unlock_irqrestore(&res->reg_slock, flags);
872}
873
874static void mixer_resource_poweron(struct mixer_context *ctx)
875{
876 struct mixer_resources *res = &ctx->mixer_res;
877
878 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
879
880 clk_enable(res->mixer);
881 clk_enable(res->vp);
882 clk_enable(res->sclk_mixer);
883
884 mixer_win_reset(ctx);
885}
886
887static void mixer_resource_poweroff(struct mixer_context *ctx)
888{
889 struct mixer_resources *res = &ctx->mixer_res;
890
891 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
892
893 clk_disable(res->mixer);
894 clk_disable(res->vp);
895 clk_disable(res->sclk_mixer);
896}
897
898static int mixer_runtime_resume(struct device *dev)
899{
900 struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev);
901
902 DRM_DEBUG_KMS("resume - start\n");
903
904 mixer_resource_poweron(ctx->ctx);
905
906 return 0;
907}
908
909static int mixer_runtime_suspend(struct device *dev)
910{
911 struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev);
912
913 DRM_DEBUG_KMS("suspend - start\n");
914
915 mixer_resource_poweroff(ctx->ctx);
916
917 return 0;
918}
919
920static const struct dev_pm_ops mixer_pm_ops = {
921 .runtime_suspend = mixer_runtime_suspend,
922 .runtime_resume = mixer_runtime_resume,
923};
924
925static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, 927static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
926 struct platform_device *pdev) 928 struct platform_device *pdev)
927{ 929{
@@ -931,7 +933,6 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
931 struct resource *res; 933 struct resource *res;
932 int ret; 934 int ret;
933 935
934 mixer_res->dev = dev;
935 spin_lock_init(&mixer_res->reg_slock); 936 spin_lock_init(&mixer_res->reg_slock);
936 937
937 mixer_res->mixer = clk_get(dev, "mixer"); 938 mixer_res->mixer = clk_get(dev, "mixer");
@@ -1027,7 +1028,6 @@ fail:
1027 clk_put(mixer_res->vp); 1028 clk_put(mixer_res->vp);
1028 if (!IS_ERR_OR_NULL(mixer_res->mixer)) 1029 if (!IS_ERR_OR_NULL(mixer_res->mixer))
1029 clk_put(mixer_res->mixer); 1030 clk_put(mixer_res->mixer);
1030 mixer_res->dev = NULL;
1031 return ret; 1031 return ret;
1032} 1032}
1033 1033
@@ -1035,7 +1035,6 @@ static void mixer_resources_cleanup(struct mixer_context *ctx)
1035{ 1035{
1036 struct mixer_resources *res = &ctx->mixer_res; 1036 struct mixer_resources *res = &ctx->mixer_res;
1037 1037
1038 disable_irq(res->irq);
1039 free_irq(res->irq, ctx); 1038 free_irq(res->irq, ctx);
1040 1039
1041 iounmap(res->vp_regs); 1040 iounmap(res->vp_regs);
@@ -1064,6 +1063,9 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1064 return -ENOMEM; 1063 return -ENOMEM;
1065 } 1064 }
1066 1065
1066 mutex_init(&ctx->mixer_mutex);
1067
1068 ctx->dev = &pdev->dev;
1067 drm_hdmi_ctx->ctx = (void *)ctx; 1069 drm_hdmi_ctx->ctx = (void *)ctx;
1068 1070
1069 platform_set_drvdata(pdev, drm_hdmi_ctx); 1071 platform_set_drvdata(pdev, drm_hdmi_ctx);
@@ -1076,7 +1078,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1076 /* register specific callback point to common hdmi. */ 1078 /* register specific callback point to common hdmi. */
1077 exynos_mixer_ops_register(&mixer_ops); 1079 exynos_mixer_ops_register(&mixer_ops);
1078 1080
1079 mixer_resource_poweron(ctx); 1081 pm_runtime_enable(dev);
1080 1082
1081 return 0; 1083 return 0;
1082 1084
@@ -1095,7 +1097,8 @@ static int mixer_remove(struct platform_device *pdev)
1095 1097
1096 dev_info(dev, "remove successful\n"); 1098 dev_info(dev, "remove successful\n");
1097 1099
1098 mixer_resource_poweroff(ctx); 1100 pm_runtime_disable(&pdev->dev);
1101
1099 mixer_resources_cleanup(ctx); 1102 mixer_resources_cleanup(ctx);
1100 1103
1101 return 0; 1104 return 0;
@@ -1105,7 +1108,6 @@ struct platform_driver mixer_driver = {
1105 .driver = { 1108 .driver = {
1106 .name = "s5p-mixer", 1109 .name = "s5p-mixer",
1107 .owner = THIS_MODULE, 1110 .owner = THIS_MODULE,
1108 .pm = &mixer_pm_ops,
1109 }, 1111 },
1110 .probe = mixer_probe, 1112 .probe = mixer_probe,
1111 .remove = __devexit_p(mixer_remove), 1113 .remove = __devexit_p(mixer_remove),