aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-11 20:10:53 -0400
committerDave Airlie <airlied@redhat.com>2016-05-11 20:10:53 -0400
commit6d23abf58a9afd3bc28aaf0384155b04c4b77912 (patch)
tree4ba843ececa274bca4b5b484ca7fd44dd9760551
parent19ea5da07a1f315191212e094ec44fb1caec9580 (diff)
parentdd65a6867454117ecaeb8944dc231a4737681782 (diff)
Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary: - expose HDMI-PHY clock to other drivers. . this patch was included in below patch series but I missed. http://www.spinics.net/lists/dri-devel/msg103097.html - some fixups about DECON5433 driver . this patch corrects vblank handling and fixes up trigger configuration. - use generic functions - gem_prime_mmap and dma_buf_mmap. - use DMA-Mapping API instead of specific one. - some code cleanups and fixeups. * 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos/decon5433: fix trigger configuration drm/exynos/dsi: use of_graph_get_endpoint_by_regs helper drm/exynos/dpi: use of_graph_get_endpoint_by_regs helper drm/exynos: Nuke dummy fb->dirty callback drm/exynos: use directly DMA mapping APIs on g2d drm/exynos/hdmi: Don't print error on deferral due to regulators drm/exynos: fix imported dma-buf to be mapped drm/exynos: support gem_prime_mmap drm/exynos: fimd: harden fimd_calc_clkdiv() drm/exynos: fix cancel page flip code drm/exynos/decon5433: do not use unnecessary software trigger drm/exynos/decon5433: handle vblank in vblank interrupt drm/exynos/hdmi: expose HDMI-PHY clock as pipeline clock
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c69
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c57
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c70
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h12
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c73
11 files changed, 120 insertions, 223 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 4ab5bfc23647..ac21b4000835 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -147,11 +147,13 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
147 val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F; 147 val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
148 writel(val, ctx->addr + DECON_CMU); 148 writel(val, ctx->addr + DECON_CMU);
149 149
150 if (ctx->out_type & (IFTYPE_I80 | I80_HW_TRG))
151 decon_setup_trigger(ctx);
152
150 /* lcd on and use command if */ 153 /* lcd on and use command if */
151 val = VIDOUT_LCD_ON; 154 val = VIDOUT_LCD_ON;
152 if (ctx->out_type & IFTYPE_I80) { 155 if (ctx->out_type & IFTYPE_I80) {
153 val |= VIDOUT_COMMAND_IF; 156 val |= VIDOUT_COMMAND_IF;
154 decon_setup_trigger(ctx);
155 } else { 157 } else {
156 val |= VIDOUT_RGB_IF; 158 val |= VIDOUT_RGB_IF;
157 } 159 }
@@ -376,9 +378,6 @@ static void decon_swreset(struct decon_context *ctx)
376 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1); 378 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
377 writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN, 379 writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
378 ctx->addr + DECON_CRCCTRL); 380 ctx->addr + DECON_CRCCTRL);
379
380 if (ctx->out_type & IFTYPE_I80)
381 decon_setup_trigger(ctx);
382} 381}
383 382
384static void decon_enable(struct exynos_drm_crtc *crtc) 383static void decon_enable(struct exynos_drm_crtc *crtc)
@@ -434,13 +433,12 @@ static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
434{ 433{
435 struct decon_context *ctx = crtc->ctx; 434 struct decon_context *ctx = crtc->ctx;
436 435
437 if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags)) 436 if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) ||
437 (ctx->out_type & I80_HW_TRG))
438 return; 438 return;
439 439
440 if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags)) 440 if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
441 decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0); 441 decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
442
443 drm_crtc_handle_vblank(&ctx->crtc->base);
444} 442}
445 443
446static void decon_clear_channels(struct exynos_drm_crtc *crtc) 444static void decon_clear_channels(struct exynos_drm_crtc *crtc)
@@ -573,6 +571,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
573 571
574 /* clear */ 572 /* clear */
575 writel(val, ctx->addr + DECON_VIDINTCON1); 573 writel(val, ctx->addr + DECON_VIDINTCON1);
574 drm_crtc_handle_vblank(&ctx->crtc->base);
576 } 575 }
577 576
578out: 577out:
@@ -648,9 +647,8 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
648 647
649 if (ctx->out_type & IFTYPE_HDMI) { 648 if (ctx->out_type & IFTYPE_HDMI) {
650 ctx->first_win = 1; 649 ctx->first_win = 1;
651 ctx->out_type = IFTYPE_I80;
652 } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) { 650 } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
653 ctx->out_type = IFTYPE_I80; 651 ctx->out_type |= IFTYPE_I80;
654 } 652 }
655 653
656 for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 654 for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 50dd33d5045d..785ffa6cc309 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -233,20 +233,15 @@ void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
233 unsigned long flags; 233 unsigned long flags;
234 234
235 spin_lock_irqsave(&crtc->dev->event_lock, flags); 235 spin_lock_irqsave(&crtc->dev->event_lock, flags);
236
236 e = exynos_crtc->event; 237 e = exynos_crtc->event;
237 if (e && e->base.file_priv == file) { 238 if (e && e->base.file_priv == file) {
238 exynos_crtc->event = NULL; 239 exynos_crtc->event = NULL;
239 /*
240 * event will be destroyed by core part
241 * so below line should be removed later with core changes
242 */
243 e->base.destroy(&e->base);
244 /*
245 * event_space will be increased by core part
246 * so below line should be removed later with core changes.
247 */
248 file->event_space += sizeof(e->event);
249 atomic_dec(&exynos_crtc->pending_update); 240 atomic_dec(&exynos_crtc->pending_update);
250 } 241 }
242
251 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 243 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
244
245 if (e && e->base.file_priv == file)
246 drm_event_cancel_free(crtc->dev, &e->base);
252} 247}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 75e570f45259..5e38e749ac17 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -15,6 +15,7 @@
15#include <drm/drm_panel.h> 15#include <drm/drm_panel.h>
16#include <drm/drm_atomic_helper.h> 16#include <drm/drm_atomic_helper.h>
17 17
18#include <linux/of_graph.h>
18#include <linux/regulator/consumer.h> 19#include <linux/regulator/consumer.h>
19 20
20#include <video/of_videomode.h> 21#include <video/of_videomode.h>
@@ -164,67 +165,6 @@ static const struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
164 .destroy = drm_encoder_cleanup, 165 .destroy = drm_encoder_cleanup,
165}; 166};
166 167
167/* of_* functions will be removed after merge of of_graph patches */
168static struct device_node *
169of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
170{
171 struct device_node *np;
172
173 for_each_child_of_node(parent, np) {
174 u32 r;
175
176 if (!np->name || of_node_cmp(np->name, name))
177 continue;
178
179 if (of_property_read_u32(np, "reg", &r) < 0)
180 r = 0;
181
182 if (reg == r)
183 break;
184 }
185
186 return np;
187}
188
189static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
190 u32 reg)
191{
192 struct device_node *ports, *port;
193
194 ports = of_get_child_by_name(parent, "ports");
195 if (ports)
196 parent = ports;
197
198 port = of_get_child_by_name_reg(parent, "port", reg);
199
200 of_node_put(ports);
201
202 return port;
203}
204
205static struct device_node *
206of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
207{
208 return of_get_child_by_name_reg(port, "endpoint", reg);
209}
210
211static struct device_node *
212of_graph_get_remote_port_parent(const struct device_node *node)
213{
214 struct device_node *np;
215 unsigned int depth;
216
217 np = of_parse_phandle(node, "remote-endpoint", 0);
218
219 /* Walk 3 levels up only if there is 'ports' node. */
220 for (depth = 3; depth && np; depth--) {
221 np = of_get_next_parent(np);
222 if (depth == 2 && of_node_cmp(np->name, "ports"))
223 break;
224 }
225 return np;
226}
227
228enum { 168enum {
229 FIMD_PORT_IN0, 169 FIMD_PORT_IN0,
230 FIMD_PORT_IN1, 170 FIMD_PORT_IN1,
@@ -237,12 +177,7 @@ static struct device_node *exynos_dpi_of_find_panel_node(struct device *dev)
237{ 177{
238 struct device_node *np, *ep; 178 struct device_node *np, *ep;
239 179
240 np = of_graph_get_port_by_reg(dev->of_node, FIMD_PORT_RGB); 180 ep = of_graph_get_endpoint_by_regs(dev->of_node, FIMD_PORT_RGB, 0);
241 if (!np)
242 return NULL;
243
244 ep = of_graph_get_endpoint_by_reg(np, 0);
245 of_node_put(np);
246 if (!ep) 181 if (!ep)
247 return NULL; 182 return NULL;
248 183
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 8ff355ddcf51..6c4dd49de993 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -431,6 +431,7 @@ static struct drm_driver exynos_drm_driver = {
431 .gem_prime_import_sg_table = exynos_drm_gem_prime_import_sg_table, 431 .gem_prime_import_sg_table = exynos_drm_gem_prime_import_sg_table,
432 .gem_prime_vmap = exynos_drm_gem_prime_vmap, 432 .gem_prime_vmap = exynos_drm_gem_prime_vmap,
433 .gem_prime_vunmap = exynos_drm_gem_prime_vunmap, 433 .gem_prime_vunmap = exynos_drm_gem_prime_vunmap,
434 .gem_prime_mmap = exynos_drm_gem_prime_mmap,
434 .ioctls = exynos_ioctls, 435 .ioctls = exynos_ioctls,
435 .num_ioctls = ARRAY_SIZE(exynos_ioctls), 436 .num_ioctls = ARRAY_SIZE(exynos_ioctls),
436 .fops = &exynos_drm_driver_fops, 437 .fops = &exynos_drm_driver_fops,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 72c3565d22ee..601ecf8006a7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1632,50 +1632,6 @@ static const struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
1632 1632
1633MODULE_DEVICE_TABLE(of, exynos_dsi_of_match); 1633MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
1634 1634
1635/* of_* functions will be removed after merge of of_graph patches */
1636static struct device_node *
1637of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
1638{
1639 struct device_node *np;
1640
1641 for_each_child_of_node(parent, np) {
1642 u32 r;
1643
1644 if (!np->name || of_node_cmp(np->name, name))
1645 continue;
1646
1647 if (of_property_read_u32(np, "reg", &r) < 0)
1648 r = 0;
1649
1650 if (reg == r)
1651 break;
1652 }
1653
1654 return np;
1655}
1656
1657static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
1658 u32 reg)
1659{
1660 struct device_node *ports, *port;
1661
1662 ports = of_get_child_by_name(parent, "ports");
1663 if (ports)
1664 parent = ports;
1665
1666 port = of_get_child_by_name_reg(parent, "port", reg);
1667
1668 of_node_put(ports);
1669
1670 return port;
1671}
1672
1673static struct device_node *
1674of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
1675{
1676 return of_get_child_by_name_reg(port, "endpoint", reg);
1677}
1678
1679static int exynos_dsi_of_read_u32(const struct device_node *np, 1635static int exynos_dsi_of_read_u32(const struct device_node *np,
1680 const char *propname, u32 *out_value) 1636 const char *propname, u32 *out_value)
1681{ 1637{
@@ -1697,7 +1653,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
1697{ 1653{
1698 struct device *dev = dsi->dev; 1654 struct device *dev = dsi->dev;
1699 struct device_node *node = dev->of_node; 1655 struct device_node *node = dev->of_node;
1700 struct device_node *port, *ep; 1656 struct device_node *ep;
1701 int ret; 1657 int ret;
1702 1658
1703 ret = exynos_dsi_of_read_u32(node, "samsung,pll-clock-frequency", 1659 ret = exynos_dsi_of_read_u32(node, "samsung,pll-clock-frequency",
@@ -1705,16 +1661,9 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
1705 if (ret < 0) 1661 if (ret < 0)
1706 return ret; 1662 return ret;
1707 1663
1708 port = of_graph_get_port_by_reg(node, DSI_PORT_OUT); 1664 ep = of_graph_get_endpoint_by_regs(node, DSI_PORT_OUT, 0);
1709 if (!port) {
1710 dev_err(dev, "no output port specified\n");
1711 return -EINVAL;
1712 }
1713
1714 ep = of_graph_get_endpoint_by_reg(port, 0);
1715 of_node_put(port);
1716 if (!ep) { 1665 if (!ep) {
1717 dev_err(dev, "no endpoint specified in output port\n"); 1666 dev_err(dev, "no output port with endpoint specified\n");
1718 return -EINVAL; 1667 return -EINVAL;
1719 } 1668 }
1720 1669
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 81cc5537cf25..f851a40ac6cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -97,20 +97,9 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
97 &exynos_fb->exynos_gem[0]->base, handle); 97 &exynos_fb->exynos_gem[0]->base, handle);
98} 98}
99 99
100static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
101 struct drm_file *file_priv, unsigned flags,
102 unsigned color, struct drm_clip_rect *clips,
103 unsigned num_clips)
104{
105 /* TODO */
106
107 return 0;
108}
109
110static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = { 100static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
111 .destroy = exynos_drm_fb_destroy, 101 .destroy = exynos_drm_fb_destroy,
112 .create_handle = exynos_drm_fb_create_handle, 102 .create_handle = exynos_drm_fb_create_handle,
113 .dirty = exynos_drm_fb_dirty,
114}; 103};
115 104
116struct drm_framebuffer * 105struct drm_framebuffer *
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index cec508f9a335..3efe1aa89416 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -397,9 +397,16 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc)
397static u32 fimd_calc_clkdiv(struct fimd_context *ctx, 397static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
398 const struct drm_display_mode *mode) 398 const struct drm_display_mode *mode)
399{ 399{
400 unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh; 400 unsigned long ideal_clk;
401 u32 clkdiv; 401 u32 clkdiv;
402 402
403 if (mode->clock == 0) {
404 DRM_ERROR("Mode has zero clock value.\n");
405 return 0xff;
406 }
407
408 ideal_clk = mode->clock * 1000;
409
403 if (ctx->i80_if) { 410 if (ctx->i80_if) {
404 /* 411 /*
405 * The frame done interrupt should be occurred prior to the 412 * The frame done interrupt should be occurred prior to the
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 193d3602dffb..493552368295 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -383,8 +383,8 @@ static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev,
383 return; 383 return;
384 384
385out: 385out:
386 exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt, 386 dma_unmap_sg(to_dma_dev(drm_dev), g2d_userptr->sgt->sgl,
387 DMA_BIDIRECTIONAL); 387 g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
388 388
389 pages = frame_vector_pages(g2d_userptr->vec); 389 pages = frame_vector_pages(g2d_userptr->vec);
390 if (!IS_ERR(pages)) { 390 if (!IS_ERR(pages)) {
@@ -501,10 +501,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
501 501
502 g2d_userptr->sgt = sgt; 502 g2d_userptr->sgt = sgt;
503 503
504 ret = exynos_gem_map_sgt_with_dma(drm_dev, g2d_userptr->sgt, 504 if (!dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents,
505 DMA_BIDIRECTIONAL); 505 DMA_BIDIRECTIONAL)) {
506 if (ret < 0) {
507 DRM_ERROR("failed to map sgt with dma region.\n"); 506 DRM_ERROR("failed to map sgt with dma region.\n");
507 ret = -ENOMEM;
508 goto err_sg_free_table; 508 goto err_sg_free_table;
509 } 509 }
510 510
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 6fb98f4c3544..72d9414bd944 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -378,28 +378,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
378 return 0; 378 return 0;
379} 379}
380 380
381int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
382 struct sg_table *sgt,
383 enum dma_data_direction dir)
384{
385 int nents;
386
387 nents = dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
388 if (!nents) {
389 DRM_ERROR("failed to map sgl with dma.\n");
390 return nents;
391 }
392
393 return 0;
394}
395
396void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
397 struct sg_table *sgt,
398 enum dma_data_direction dir)
399{
400 dma_unmap_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
401}
402
403void exynos_drm_gem_free_object(struct drm_gem_object *obj) 381void exynos_drm_gem_free_object(struct drm_gem_object *obj)
404{ 382{
405 exynos_drm_gem_destroy(to_exynos_gem(obj)); 383 exynos_drm_gem_destroy(to_exynos_gem(obj));
@@ -503,22 +481,12 @@ out:
503 } 481 }
504} 482}
505 483
506int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) 484static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj,
485 struct vm_area_struct *vma)
507{ 486{
508 struct exynos_drm_gem *exynos_gem; 487 struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
509 struct drm_gem_object *obj;
510 int ret; 488 int ret;
511 489
512 /* set vm_area_struct. */
513 ret = drm_gem_mmap(filp, vma);
514 if (ret < 0) {
515 DRM_ERROR("failed to mmap.\n");
516 return ret;
517 }
518
519 obj = vma->vm_private_data;
520 exynos_gem = to_exynos_gem(obj);
521
522 DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags); 490 DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);
523 491
524 /* non-cachable as default. */ 492 /* non-cachable as default. */
@@ -543,6 +511,26 @@ err_close_vm:
543 return ret; 511 return ret;
544} 512}
545 513
514int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
515{
516 struct drm_gem_object *obj;
517 int ret;
518
519 /* set vm_area_struct. */
520 ret = drm_gem_mmap(filp, vma);
521 if (ret < 0) {
522 DRM_ERROR("failed to mmap.\n");
523 return ret;
524 }
525
526 obj = vma->vm_private_data;
527
528 if (obj->import_attach)
529 return dma_buf_mmap(obj->dma_buf, vma, 0);
530
531 return exynos_drm_gem_mmap_obj(obj, vma);
532}
533
546/* low-level interface prime helpers */ 534/* low-level interface prime helpers */
547struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj) 535struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
548{ 536{
@@ -617,3 +605,15 @@ void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
617{ 605{
618 /* Nothing to do */ 606 /* Nothing to do */
619} 607}
608
609int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
610 struct vm_area_struct *vma)
611{
612 int ret;
613
614 ret = drm_gem_mmap_obj(obj, obj->size, vma);
615 if (ret < 0)
616 return ret;
617
618 return exynos_drm_gem_mmap_obj(obj, vma);
619}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 00223052b87b..78100742281d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -121,16 +121,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
121/* set vm_flags and we can change the vm attribute to other one at here. */ 121/* set vm_flags and we can change the vm attribute to other one at here. */
122int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 122int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
123 123
124/* map sgt with dma region. */
125int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
126 struct sg_table *sgt,
127 enum dma_data_direction dir);
128
129/* unmap sgt from dma region. */
130void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
131 struct sg_table *sgt,
132 enum dma_data_direction dir);
133
134/* low-level interface prime helpers */ 124/* low-level interface prime helpers */
135struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj); 125struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj);
136struct drm_gem_object * 126struct drm_gem_object *
@@ -139,5 +129,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
139 struct sg_table *sgt); 129 struct sg_table *sgt);
140void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj); 130void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj);
141void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); 131void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
132int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
133 struct vm_area_struct *vma);
142 134
143#endif 135#endif
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 0f87acb4cf21..6cd09944405f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -146,6 +146,7 @@ struct hdmi_context {
146 struct clk **clk_muxes; 146 struct clk **clk_muxes;
147 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; 147 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)];
148 struct regulator *reg_hdmi_en; 148 struct regulator *reg_hdmi_en;
149 struct exynos_drm_clk phy_clk;
149}; 150};
150 151
151static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e) 152static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
@@ -1445,7 +1446,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1445 1446
1446static void hdmi_conf_apply(struct hdmi_context *hdata) 1447static void hdmi_conf_apply(struct hdmi_context *hdata)
1447{ 1448{
1448 hdmiphy_conf_apply(hdata);
1449 hdmi_start(hdata, false); 1449 hdmi_start(hdata, false);
1450 hdmi_conf_init(hdata); 1450 hdmi_conf_init(hdata);
1451 hdmi_audio_init(hdata); 1451 hdmi_audio_init(hdata);
@@ -1478,10 +1478,8 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1478 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); 1478 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1479} 1479}
1480 1480
1481static void hdmi_enable(struct drm_encoder *encoder) 1481static void hdmiphy_enable(struct hdmi_context *hdata)
1482{ 1482{
1483 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1484
1485 if (hdata->powered) 1483 if (hdata->powered)
1486 return; 1484 return;
1487 1485
@@ -1497,11 +1495,40 @@ static void hdmi_enable(struct drm_encoder *encoder)
1497 1495
1498 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN); 1496 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1499 1497
1500 hdmi_conf_apply(hdata); 1498 hdmiphy_conf_apply(hdata);
1501 1499
1502 hdata->powered = true; 1500 hdata->powered = true;
1503} 1501}
1504 1502
1503static void hdmiphy_disable(struct hdmi_context *hdata)
1504{
1505 if (!hdata->powered)
1506 return;
1507
1508 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1509
1510 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1511
1512 hdmi_set_refclk(hdata, false);
1513
1514 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1515 PMU_HDMI_PHY_ENABLE_BIT, 0);
1516
1517 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1518
1519 pm_runtime_put_sync(hdata->dev);
1520
1521 hdata->powered = false;
1522}
1523
1524static void hdmi_enable(struct drm_encoder *encoder)
1525{
1526 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1527
1528 hdmiphy_enable(hdata);
1529 hdmi_conf_apply(hdata);
1530}
1531
1505static void hdmi_disable(struct drm_encoder *encoder) 1532static void hdmi_disable(struct drm_encoder *encoder)
1506{ 1533{
1507 struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1534 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
@@ -1525,22 +1552,9 @@ static void hdmi_disable(struct drm_encoder *encoder)
1525 if (funcs && funcs->disable) 1552 if (funcs && funcs->disable)
1526 (*funcs->disable)(crtc); 1553 (*funcs->disable)(crtc);
1527 1554
1528 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1529
1530 cancel_delayed_work(&hdata->hotplug_work); 1555 cancel_delayed_work(&hdata->hotplug_work);
1531 1556
1532 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); 1557 hdmiphy_disable(hdata);
1533
1534 hdmi_set_refclk(hdata, false);
1535
1536 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1537 PMU_HDMI_PHY_ENABLE_BIT, 0);
1538
1539 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1540
1541 pm_runtime_put_sync(hdata->dev);
1542
1543 hdata->powered = false;
1544} 1558}
1545 1559
1546static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { 1560static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@@ -1625,6 +1639,17 @@ static int hdmi_clk_init(struct hdmi_context *hdata)
1625} 1639}
1626 1640
1627 1641
1642static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1643{
1644 struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1645 phy_clk);
1646
1647 if (enable)
1648 hdmiphy_enable(hdata);
1649 else
1650 hdmiphy_disable(hdata);
1651}
1652
1628static int hdmi_resources_init(struct hdmi_context *hdata) 1653static int hdmi_resources_init(struct hdmi_context *hdata)
1629{ 1654{
1630 struct device *dev = hdata->dev; 1655 struct device *dev = hdata->dev;
@@ -1658,7 +1683,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
1658 } 1683 }
1659 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk); 1684 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1660 if (ret) { 1685 if (ret) {
1661 DRM_ERROR("failed to get regulators\n"); 1686 if (ret != -EPROBE_DEFER)
1687 DRM_ERROR("failed to get regulators\n");
1662 return ret; 1688 return ret;
1663 } 1689 }
1664 1690
@@ -1710,6 +1736,10 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
1710 if (pipe < 0) 1736 if (pipe < 0)
1711 return pipe; 1737 return pipe;
1712 1738
1739 hdata->phy_clk.enable = hdmiphy_clk_enable;
1740
1741 exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk;
1742
1713 encoder->possible_crtcs = 1 << pipe; 1743 encoder->possible_crtcs = 1 << pipe;
1714 1744
1715 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 1745 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
@@ -1777,7 +1807,8 @@ static int hdmi_probe(struct platform_device *pdev)
1777 1807
1778 ret = hdmi_resources_init(hdata); 1808 ret = hdmi_resources_init(hdata);
1779 if (ret) { 1809 if (ret) {
1780 DRM_ERROR("hdmi_resources_init failed\n"); 1810 if (ret != -EPROBE_DEFER)
1811 DRM_ERROR("hdmi_resources_init failed\n");
1781 return ret; 1812 return ret;
1782 } 1813 }
1783 1814