]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'exynos-drm-next-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel...
authorDave Airlie <airlied@redhat.com>
Tue, 6 Jun 2017 06:54:27 +0000 (16:54 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 6 Jun 2017 06:54:27 +0000 (16:54 +1000)
Summary:
- Rework vblank handling
  . This patch series adds frame counter callback and removes
    unnecessary pipe relevnt fields and simplifies event handling.
- clean up and fix up sw-trigger relevant code
  . This patch series moves TE relevant code from Panel and HDMI
    to DECON driver to fix a race between interrupt handlers and
    DECON disable, and to fix timeout issue at wait-for-vblank.
  . It removes unnecessary flags and check code specific to Exynos driver.

* tag 'exynos-drm-next-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (27 commits)
  drm/exynos/decon5433: remove useless check
  drm/exynos/decon5433: kill BIT_SUSPENDED flag
  drm/exynos/decon5433: kill BIT_WIN_UPDATED flag
  drm/exynos/decon5433: kill BIT_CLKS_ENABLED flag
  drm/exynos/decon5433: kill BIT_IRQS_ENABLED flag
  drm/exynos/decon5433: move TE handling to DECON
  dt-bindings: exynos5433-decon: add TE interrupt binding
  dt-bindings: exynos5433-decon: fix interrupts bindings
  drm/exynos/decon5433: always do sw-trigger when vblanks enabled
  drm/exynos: mixer: document YCbCr magic numbers
  drm/exynos: mixer: simplify mixer_cfg_rgb_fmt()
  drm/exynos/dsi: fix bridge_node DT parsing
  drm/exynos/hdmi: fix pipeline disable order
  drm/exynos/decon5433: simplify shadow protect code
  drm/exynos/decon5433: kill BIT_IRQS_ENABLED
  drm/exynos/decon5433: kill DECON_UPDATE workaround
  drm/exynos: kill mode_set_nofb callback
  drm/exynos: kill pipe field from drivers contexts
  drm/exynos: set plane possible_crtcs in exynos_plane_init
  drm/exynos: kill exynos_drm_private::pipe
  ...

15 files changed:
Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_plane.h
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/exynos/regs-mixer.h
include/video/exynos5433_decon.h

index c9fd7b3807e76ed677379dd807dd3743c9ab7538..549c538b38a5b7a9e31b8366a954d1a79d57edb6 100644 (file)
@@ -8,12 +8,13 @@ Required properties:
 - compatible: value should be one of:
        "samsung,exynos5433-decon", "samsung,exynos5433-decon-tv";
 - reg: physical base address and length of the DECON registers set.
-- interrupts: should contain a list of all DECON IP block interrupts in the
-             order: VSYNC, LCD_SYSTEM. The interrupt specifier format
-             depends on the interrupt controller used.
-- interrupt-names: should contain the interrupt names: "vsync", "lcd_sys"
-                  in the same order as they were listed in the interrupts
-                  property.
+- interrupt-names: should contain the interrupt names depending on mode of work:
+               video mode: "vsync",
+               command mode: "lcd_sys",
+               command mode with software trigger: "lcd_sys", "te".
+- interrupts or interrupts-extended: list of interrupt specifiers corresponding
+               to names privided in interrupt-names, as described in
+               interrupt-controller/interrupts.txt
 - clocks: must include clock specifiers corresponding to entries in the
          clock-names property.
 - clock-names: list of clock names sorted in the same order as the clocks
index c0e8d3302292c9c9329ca4795b4d9ffb3465a178..5792ca88ab7a3718a8e24e58003468ac95e9b46b 100644 (file)
@@ -47,14 +47,6 @@ static const char * const decon_clks_name[] = {
        "sclk_decon_eclk",
 };
 
-enum decon_flag_bits {
-       BIT_CLKS_ENABLED,
-       BIT_IRQS_ENABLED,
-       BIT_WIN_UPDATED,
-       BIT_SUSPENDED,
-       BIT_REQUEST_UPDATE
-};
-
 struct decon_context {
        struct device                   *dev;
        struct drm_device               *drm_dev;
@@ -64,8 +56,8 @@ struct decon_context {
        void __iomem                    *addr;
        struct regmap                   *sysreg;
        struct clk                      *clks[ARRAY_SIZE(decon_clks_name)];
-       int                             pipe;
-       unsigned long                   flags;
+       unsigned int                    irq;
+       unsigned int                    te_irq;
        unsigned long                   out_type;
        int                             first_win;
        spinlock_t                      vblank_lock;
@@ -97,18 +89,17 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
        struct decon_context *ctx = crtc->ctx;
        u32 val;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return -EPERM;
+       val = VIDINTCON0_INTEN;
+       if (ctx->out_type & IFTYPE_I80)
+               val |= VIDINTCON0_FRAMEDONE;
+       else
+               val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
 
-       if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
-               val = VIDINTCON0_INTEN;
-               if (ctx->out_type & IFTYPE_I80)
-                       val |= VIDINTCON0_FRAMEDONE;
-               else
-                       val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
+       writel(val, ctx->addr + DECON_VIDINTCON0);
 
-               writel(val, ctx->addr + DECON_VIDINTCON0);
-       }
+       enable_irq(ctx->irq);
+       if (!(ctx->out_type & I80_HW_TRG))
+               enable_irq(ctx->te_irq);
 
        return 0;
 }
@@ -117,11 +108,11 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
+       if (!(ctx->out_type & I80_HW_TRG))
+               disable_irq_nosync(ctx->te_irq);
+       disable_irq_nosync(ctx->irq);
 
-       if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
-               writel(0, ctx->addr + DECON_VIDINTCON0);
+       writel(0, ctx->addr + DECON_VIDINTCON0);
 }
 
 /* return number of starts/ends of frame transmissions since reset */
@@ -166,6 +157,13 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
        return frm;
 }
 
+static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
+{
+       struct decon_context *ctx = crtc->ctx;
+
+       return decon_get_frame_count(ctx, false);
+}
+
 static void decon_setup_trigger(struct decon_context *ctx)
 {
        if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
@@ -193,9 +191,6 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
        bool interlaced = false;
        u32 val;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
-
        if (ctx->out_type & IFTYPE_HDMI) {
                m->crtc_hsync_start = m->crtc_hdisplay + 10;
                m->crtc_hsync_end = m->crtc_htotal - 92;
@@ -309,23 +304,17 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
        writel(val, ctx->addr + DECON_WINCONx(win));
 }
 
-static void decon_shadow_protect_win(struct decon_context *ctx, int win,
-                                       bool protect)
+static void decon_shadow_protect(struct decon_context *ctx, bool protect)
 {
-       decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_Wx_PROTECT(win),
+       decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_PROTECT_MASK,
                       protect ? ~0 : 0);
 }
 
 static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
-       int i;
-
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
 
-       for (i = ctx->first_win; i < WINDOWS_NR; i++)
-               decon_shadow_protect_win(ctx, i, true);
+       decon_shadow_protect(ctx, true);
 }
 
 #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
@@ -345,9 +334,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
        dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
        u32 val;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
-
        if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) {
                val = COORDINATE_X(state->crtc.x) |
                        COORDINATE_Y(state->crtc.y / 2);
@@ -390,7 +376,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 
        /* window enable */
        decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
-       set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
 }
 
 static void decon_disable_plane(struct exynos_drm_crtc *crtc,
@@ -399,32 +384,19 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
        struct decon_context *ctx = crtc->ctx;
        unsigned int win = plane->index;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
-
        decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
-       set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
 }
 
 static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
        unsigned long flags;
-       int i;
-
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
 
        spin_lock_irqsave(&ctx->vblank_lock, flags);
 
-       for (i = ctx->first_win; i < WINDOWS_NR; i++)
-               decon_shadow_protect_win(ctx, i, false);
-
-       if (test_and_clear_bit(BIT_REQUEST_UPDATE, &ctx->flags))
-               decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
+       decon_shadow_protect(ctx, false);
 
-       if (ctx->out_type & IFTYPE_I80)
-               set_bit(BIT_WIN_UPDATED, &ctx->flags);
+       decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
 
        ctx->frame_id = decon_get_frame_count(ctx, true);
 
@@ -473,21 +445,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
 
-       if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
-
        pm_runtime_get_sync(ctx->dev);
 
        exynos_drm_pipe_clk_enable(crtc, true);
 
-       set_bit(BIT_CLKS_ENABLED, &ctx->flags);
-
        decon_swreset(ctx);
 
-       /* if vblank was enabled status, enable it again. */
-       if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
-               decon_enable_vblank(ctx->crtc);
-
        decon_commit(ctx->crtc);
 }
 
@@ -496,8 +459,9 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
        struct decon_context *ctx = crtc->ctx;
        int i;
 
-       if (test_bit(BIT_SUSPENDED, &ctx->flags))
-               return;
+       if (!(ctx->out_type & I80_HW_TRG))
+               synchronize_irq(ctx->te_irq);
+       synchronize_irq(ctx->irq);
 
        /*
         * We need to make sure that all windows are disabled before we
@@ -509,25 +473,18 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
 
        decon_swreset(ctx);
 
-       clear_bit(BIT_CLKS_ENABLED, &ctx->flags);
-
        exynos_drm_pipe_clk_enable(crtc, false);
 
        pm_runtime_put_sync(ctx->dev);
-
-       set_bit(BIT_SUSPENDED, &ctx->flags);
 }
 
-static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
+static irqreturn_t decon_te_irq_handler(int irq, void *dev_id)
 {
-       struct decon_context *ctx = crtc->ctx;
+       struct decon_context *ctx = dev_id;
 
-       if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) ||
-           (ctx->out_type & I80_HW_TRG))
-               return;
+       decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
 
-       if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
-               decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
+       return IRQ_HANDLED;
 }
 
 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
@@ -543,11 +500,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
                        goto err;
        }
 
-       for (win = 0; win < WINDOWS_NR; win++) {
-               decon_shadow_protect_win(ctx, win, true);
+       decon_shadow_protect(ctx, true);
+       for (win = 0; win < WINDOWS_NR; win++)
                decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
-               decon_shadow_protect_win(ctx, win, false);
-       }
+       decon_shadow_protect(ctx, false);
 
        decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
 
@@ -564,25 +520,24 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
        .disable                = decon_disable,
        .enable_vblank          = decon_enable_vblank,
        .disable_vblank         = decon_disable_vblank,
+       .get_vblank_counter     = decon_get_vblank_counter,
        .atomic_begin           = decon_atomic_begin,
        .update_plane           = decon_update_plane,
        .disable_plane          = decon_disable_plane,
        .atomic_flush           = decon_atomic_flush,
-       .te_handler             = decon_te_irq_handler,
 };
 
 static int decon_bind(struct device *dev, struct device *master, void *data)
 {
        struct decon_context *ctx = dev_get_drvdata(dev);
        struct drm_device *drm_dev = data;
-       struct exynos_drm_private *priv = drm_dev->dev_private;
        struct exynos_drm_plane *exynos_plane;
        enum exynos_drm_output_type out_type;
        unsigned int win;
        int ret;
 
        ctx->drm_dev = drm_dev;
-       ctx->pipe = priv->pipe++;
+       drm_dev->max_vblank_count = 0xffffffff;
 
        for (win = ctx->first_win; win < WINDOWS_NR; win++) {
                int tmp = (win == ctx->first_win) ? 0 : win;
@@ -593,7 +548,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
                ctx->configs[win].type = decon_win_types[tmp];
 
                ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
-                                       1 << ctx->pipe, &ctx->configs[win]);
+                                       &ctx->configs[win]);
                if (ret)
                        return ret;
        }
@@ -602,23 +557,13 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
        out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
                                                  : EXYNOS_DISPLAY_TYPE_LCD;
        ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
-                                       ctx->pipe, out_type,
-                                       &decon_crtc_ops, ctx);
-       if (IS_ERR(ctx->crtc)) {
-               ret = PTR_ERR(ctx->crtc);
-               goto err;
-       }
+                       out_type, &decon_crtc_ops, ctx);
+       if (IS_ERR(ctx->crtc))
+               return PTR_ERR(ctx->crtc);
 
        decon_clear_channels(ctx->crtc);
 
-       ret = drm_iommu_attach_device(drm_dev, dev);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       priv->pipe--;
-       return ret;
+       return drm_iommu_attach_device(drm_dev, dev);
 }
 
 static void decon_unbind(struct device *dev, struct device *master, void *data)
@@ -659,9 +604,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
        struct decon_context *ctx = dev_id;
        u32 val;
 
-       if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
-               goto out;
-
        val = readl(ctx->addr + DECON_VIDINTCON1);
        val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
 
@@ -677,7 +619,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
                decon_handle_vblank(ctx);
        }
 
-out:
        return IRQ_HANDLED;
 }
 
@@ -732,6 +673,31 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
 
+static int decon_conf_irq(struct decon_context *ctx, const char *name,
+               irq_handler_t handler, unsigned long int flags, bool required)
+{
+       struct platform_device *pdev = to_platform_device(ctx->dev);
+       int ret, irq = platform_get_irq_byname(pdev, name);
+
+       if (irq < 0) {
+               if (irq == -EPROBE_DEFER)
+                       return irq;
+               if (required)
+                       dev_err(ctx->dev, "cannot get %s IRQ\n", name);
+               else
+                       irq = 0;
+               return irq;
+       }
+       irq_set_status_flags(irq, IRQ_NOAUTOEN);
+       ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
+       if (ret < 0) {
+               dev_err(ctx->dev, "IRQ %s request failed\n", name);
+               return ret;
+       }
+
+       return irq;
+}
+
 static int exynos5433_decon_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -744,7 +710,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
        if (!ctx)
                return -ENOMEM;
 
-       __set_bit(BIT_SUSPENDED, &ctx->flags);
        ctx->dev = dev;
        ctx->out_type = (unsigned long)of_device_get_match_data(dev);
        spin_lock_init(&ctx->vblank_lock);
@@ -755,15 +720,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
                ctx->out_type |= IFTYPE_I80;
        }
 
-       if (ctx->out_type & I80_HW_TRG) {
-               ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
-                                                       "samsung,disp-sysreg");
-               if (IS_ERR(ctx->sysreg)) {
-                       dev_err(dev, "failed to get system register\n");
-                       return PTR_ERR(ctx->sysreg);
-               }
-       }
-
        for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
                struct clk *clk;
 
@@ -786,18 +742,34 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
                return PTR_ERR(ctx->addr);
        }
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                       (ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync");
-       if (!res) {
-               dev_err(dev, "cannot find IRQ resource\n");
-               return -ENXIO;
+       if (ctx->out_type & IFTYPE_I80) {
+               ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0, true);
+               if (ret < 0)
+                       return ret;
+               ctx->irq = ret;
+
+               ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
+                                    IRQF_TRIGGER_RISING, false);
+               if (ret < 0)
+                       return ret;
+               if (ret) {
+                       ctx->te_irq = ret;
+                       ctx->out_type &= ~I80_HW_TRG;
+               }
+       } else {
+               ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0, true);
+               if (ret < 0)
+                       return ret;
+               ctx->irq = ret;
        }
 
-       ret = devm_request_irq(dev, res->start, decon_irq_handler, 0,
-                              "drm_decon", ctx);
-       if (ret < 0) {
-               dev_err(dev, "lcd_sys irq request failed\n");
-               return ret;
+       if (ctx->out_type & I80_HW_TRG) {
+               ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+                                                       "samsung,disp-sysreg");
+               if (IS_ERR(ctx->sysreg)) {
+                       dev_err(dev, "failed to get system register\n");
+                       return PTR_ERR(ctx->sysreg);
+               }
        }
 
        platform_set_drvdata(pdev, ctx);
index 48811806fa2727c540e5f5e9d0ffb1700dc08c4f..3e88269fdc2e11a5a6ee867bcb4415e48e0cbb66 100644 (file)
@@ -55,7 +55,6 @@ struct decon_context {
        unsigned long                   irq_flags;
        bool                            i80_if;
        bool                            suspended;
-       int                             pipe;
        wait_queue_head_t               wait_vsync_queue;
        atomic_t                        wait_vsync_event;
 
@@ -130,19 +129,11 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
 static int decon_ctx_initialize(struct decon_context *ctx,
                        struct drm_device *drm_dev)
 {
-       struct exynos_drm_private *priv = drm_dev->dev_private;
-       int ret;
-
        ctx->drm_dev = drm_dev;
-       ctx->pipe = priv->pipe++;
 
        decon_clear_channels(ctx->crtc);
 
-       ret = drm_iommu_attach_device(drm_dev, ctx->dev);
-       if (ret)
-               priv->pipe--;
-
-       return ret;
+       return drm_iommu_attach_device(drm_dev, ctx->dev);
 }
 
 static void decon_ctx_remove(struct decon_context *ctx)
@@ -590,7 +581,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
 static const struct exynos_drm_crtc_ops decon_crtc_ops = {
        .enable = decon_enable,
        .disable = decon_disable,
-       .commit = decon_commit,
        .enable_vblank = decon_enable_vblank,
        .disable_vblank = decon_disable_vblank,
        .atomic_begin = decon_atomic_begin,
@@ -612,7 +602,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
                writel(clear_bit, ctx->regs + VIDINTCON1);
 
        /* check the crtc is detached already from encoder */
-       if (ctx->pipe < 0 || !ctx->drm_dev)
+       if (!ctx->drm_dev)
                goto out;
 
        if (!ctx->i80_if) {
@@ -649,15 +639,14 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
                ctx->configs[i].type = decon_win_types[i];
 
                ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
-                                       1 << ctx->pipe, &ctx->configs[i]);
+                                       &ctx->configs[i]);
                if (ret)
                        return ret;
        }
 
        exynos_plane = &ctx->planes[DEFAULT_WIN];
        ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
-                                          ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
-                                          &decon_crtc_ops, ctx);
+                       EXYNOS_DISPLAY_TYPE_LCD, &decon_crtc_ops, ctx);
        if (IS_ERR(ctx->crtc)) {
                decon_ctx_remove(ctx);
                return PTR_ERR(ctx->crtc);
index 0620d3ca2d06b3142264f1b66f64d4d334340bf0..d72777f6411a73144ffb3142c2bdca2e8585ac61 100644 (file)
@@ -49,15 +49,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
        }
 }
 
-static void
-exynos_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
-{
-       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-
-       if (exynos_crtc->ops->commit)
-               exynos_crtc->ops->commit(exynos_crtc);
-}
-
 static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
                                     struct drm_crtc_state *state)
 {
@@ -93,7 +84,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
 static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
        .enable         = exynos_drm_crtc_enable,
        .disable        = exynos_drm_crtc_disable,
-       .mode_set_nofb  = exynos_drm_crtc_mode_set_nofb,
        .atomic_check   = exynos_crtc_atomic_check,
        .atomic_begin   = exynos_crtc_atomic_begin,
        .atomic_flush   = exynos_crtc_atomic_flush,
@@ -105,16 +95,15 @@ void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
        struct drm_pending_vblank_event *event = crtc->state->event;
        unsigned long flags;
 
-       if (event) {
-               crtc->state->event = NULL;
-               spin_lock_irqsave(&crtc->dev->event_lock, flags);
-               if (drm_crtc_vblank_get(crtc) == 0)
-                       drm_crtc_arm_vblank_event(crtc, event);
-               else
-                       drm_crtc_send_vblank_event(crtc, event);
-               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-       }
+       if (!event)
+               return;
+       crtc->state->event = NULL;
 
+       WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+       spin_lock_irqsave(&crtc->dev->event_lock, flags);
+       drm_crtc_arm_vblank_event(crtc, event);
+       spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 }
 
 static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
@@ -143,6 +132,16 @@ static void exynos_drm_crtc_disable_vblank(struct drm_crtc *crtc)
                exynos_crtc->ops->disable_vblank(exynos_crtc);
 }
 
+static u32 exynos_drm_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+
+       if (exynos_crtc->ops->get_vblank_counter)
+               return exynos_crtc->ops->get_vblank_counter(exynos_crtc);
+
+       return 0;
+}
+
 static const struct drm_crtc_funcs exynos_crtc_funcs = {
        .set_config     = drm_atomic_helper_set_config,
        .page_flip      = drm_atomic_helper_page_flip,
@@ -152,11 +151,11 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = {
        .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
        .enable_vblank = exynos_drm_crtc_enable_vblank,
        .disable_vblank = exynos_drm_crtc_disable_vblank,
+       .get_vblank_counter = exynos_drm_crtc_get_vblank_counter,
 };
 
 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
                                        struct drm_plane *plane,
-                                       int pipe,
                                        enum exynos_drm_output_type type,
                                        const struct exynos_drm_crtc_ops *ops,
                                        void *ctx)
@@ -169,7 +168,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
        if (!exynos_crtc)
                return ERR_PTR(-ENOMEM);
 
-       exynos_crtc->pipe = pipe;
        exynos_crtc->type = type;
        exynos_crtc->ops = ops;
        exynos_crtc->ctx = ctx;
@@ -196,13 +194,9 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
 {
        struct drm_crtc *crtc;
 
-       list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
-               struct exynos_drm_crtc *exynos_crtc;
-
-               exynos_crtc = to_exynos_crtc(crtc);
-               if (exynos_crtc->type == out_type)
-                       return exynos_crtc->pipe;
-       }
+       drm_for_each_crtc(crtc, drm_dev)
+               if (to_exynos_crtc(crtc)->type == out_type)
+                       return drm_crtc_index(crtc);
 
        return -EPERM;
 }
index 9634fe5ad5fe5a09ce220b7113e2650915bab21e..ef58b64e3d2d4f65f2e9df202ca87d0911690367 100644 (file)
@@ -19,7 +19,6 @@
 
 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
                                        struct drm_plane *plane,
-                                       int pipe,
                                        enum exynos_drm_output_type type,
                                        const struct exynos_drm_crtc_ops *ops,
                                        void *context);
index cb317693059696b3c86bda9c93c2e5ebcefad921..a93de321706bac0f9cbcb80e087120a4eed99d23 100644 (file)
@@ -115,7 +115,6 @@ struct exynos_drm_plane_config {
  *
  * @enable: enable the device
  * @disable: disable the device
- * @commit: set current hw specific display mode to hw.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
  * @atomic_check: validate state
@@ -130,9 +129,9 @@ struct exynos_drm_crtc;
 struct exynos_drm_crtc_ops {
        void (*enable)(struct exynos_drm_crtc *crtc);
        void (*disable)(struct exynos_drm_crtc *crtc);
-       void (*commit)(struct exynos_drm_crtc *crtc);
        int (*enable_vblank)(struct exynos_drm_crtc *crtc);
        void (*disable_vblank)(struct exynos_drm_crtc *crtc);
+       u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
        int (*atomic_check)(struct exynos_drm_crtc *crtc,
                            struct drm_crtc_state *state);
        void (*atomic_begin)(struct exynos_drm_crtc *crtc);
@@ -153,24 +152,13 @@ struct exynos_drm_clk {
  *
  * @base: crtc object.
  * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @pipe: a crtc index created at load() with a new crtc object creation
- *     and the crtc object would be set to private->crtc array
- *     to get a crtc object corresponding to this pipe from private->crtc
- *     array when irq interrupt occurred. the reason of using this pipe is that
- *     drm framework doesn't support multiple irq yet.
- *     we can refer to the crtc to current hardware interrupt occurred through
- *     this pipe value.
- * @enabled: if the crtc is enabled or not
- * @event: vblank event that is currently queued for flip
- * @wait_update: wait all pending planes updates to finish
- * @pending_update: number of pending plane updates in this crtc
  * @ops: pointer to callbacks for exynos drm specific functionality
  * @ctx: A pointer to the crtc's implementation specific context
+ * @pipe_clk: A pointer to the crtc's pipeline clock.
  */
 struct exynos_drm_crtc {
        struct drm_crtc                 base;
        enum exynos_drm_output_type     type;
-       unsigned int                    pipe;
        const struct exynos_drm_crtc_ops        *ops;
        void                            *ctx;
        struct exynos_drm_clk           *pipe_clk;
@@ -203,7 +191,6 @@ struct drm_exynos_file_private {
  *     otherwise default one.
  * @da_space_size: size of device address space.
  *     if 0 then default value is used for it.
- * @pipe: the pipe number for this crtc/manager.
  * @pending: the crtcs that have pending updates to finish
  * @lock: protect access to @pending
  * @wait: wait an atomic commit to finish
@@ -214,8 +201,6 @@ struct exynos_drm_private {
        struct device *dma_dev;
        void *mapping;
 
-       unsigned int pipe;
-
        /* for atomic commit */
        u32                     pending;
        spinlock_t              lock;
index fc4fda738906251de7a6047c3fc8f3699c469b79..a11b79596e2f8d483c113b78d1df7568d59a48d4 100644 (file)
@@ -1633,7 +1633,6 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
 {
        struct device *dev = dsi->dev;
        struct device_node *node = dev->of_node;
-       struct device_node *ep;
        int ret;
 
        ret = exynos_dsi_of_read_u32(node, "samsung,pll-clock-frequency",
@@ -1641,32 +1640,21 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
        if (ret < 0)
                return ret;
 
-       ep = of_graph_get_endpoint_by_regs(node, DSI_PORT_OUT, 0);
-       if (!ep) {
-               dev_err(dev, "no output port with endpoint specified\n");
-               return -EINVAL;
-       }
-
-       ret = exynos_dsi_of_read_u32(ep, "samsung,burst-clock-frequency",
+       ret = exynos_dsi_of_read_u32(node, "samsung,burst-clock-frequency",
                                     &dsi->burst_clk_rate);
        if (ret < 0)
-               goto end;
+               return ret;
 
-       ret = exynos_dsi_of_read_u32(ep, "samsung,esc-clock-frequency",
+       ret = exynos_dsi_of_read_u32(node, "samsung,esc-clock-frequency",
                                     &dsi->esc_clk_rate);
        if (ret < 0)
-               goto end;
-
-       of_node_put(ep);
+               return ret;
 
-       dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_OUT, 0);
+       dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
        if (!dsi->bridge_node)
                return -EINVAL;
 
-end:
-       of_node_put(ep);
-
-       return ret;
+       return 0;
 }
 
 static int exynos_dsi_bind(struct device *dev, struct device *master,
@@ -1817,6 +1805,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+       struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
+       of_node_put(dsi->bridge_node);
+
        pm_runtime_disable(&pdev->dev);
 
        component_del(&pdev->dev, &exynos_dsi_component_ops);
index 3f04d72c448d386fc9f646e1033c8528406b107e..60f93cad6643d9881b25b5dbc25fa1ebaabf88b8 100644 (file)
@@ -179,7 +179,6 @@ struct fimd_context {
        u32                             i80ifcon;
        bool                            i80_if;
        bool                            suspended;
-       int                             pipe;
        wait_queue_head_t               wait_vsync_queue;
        atomic_t                        wait_vsync_event;
        atomic_t                        win_updated;
@@ -354,18 +353,13 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc)
 
        /* Wait for vsync, as disable channel takes effect at next vsync */
        if (ch_enabled) {
-               int pipe = ctx->pipe;
-
-               /* ensure that vblank interrupt won't be reported to core */
                ctx->suspended = false;
-               ctx->pipe = -1;
 
                fimd_enable_vblank(ctx->crtc);
                fimd_wait_for_vblank(ctx->crtc);
                fimd_disable_vblank(ctx->crtc);
 
                ctx->suspended = true;
-               ctx->pipe = pipe;
        }
 
        clk_disable_unprepare(ctx->lcd_clk);
@@ -899,7 +893,7 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc)
        u32 trg_type = ctx->driver_data->trg_type;
 
        /* Checks the crtc is detached already from encoder */
-       if (ctx->pipe < 0 || !ctx->drm_dev)
+       if (!ctx->drm_dev)
                return;
 
        if (trg_type == I80_HW_TRG)
@@ -934,7 +928,6 @@ static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable)
 static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
        .enable = fimd_enable,
        .disable = fimd_disable,
-       .commit = fimd_commit,
        .enable_vblank = fimd_enable_vblank,
        .disable_vblank = fimd_disable_vblank,
        .atomic_begin = fimd_atomic_begin,
@@ -957,7 +950,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
                writel(clear_bit, ctx->regs + VIDINTCON1);
 
        /* check the crtc is detached already from encoder */
-       if (ctx->pipe < 0 || !ctx->drm_dev)
+       if (!ctx->drm_dev)
                goto out;
 
        if (!ctx->i80_if)
@@ -982,13 +975,11 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 {
        struct fimd_context *ctx = dev_get_drvdata(dev);
        struct drm_device *drm_dev = data;
-       struct exynos_drm_private *priv = drm_dev->dev_private;
        struct exynos_drm_plane *exynos_plane;
        unsigned int i;
        int ret;
 
        ctx->drm_dev = drm_dev;
-       ctx->pipe = priv->pipe++;
 
        for (i = 0; i < WINDOWS_NR; i++) {
                ctx->configs[i].pixel_formats = fimd_formats;
@@ -996,15 +987,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
                ctx->configs[i].zpos = i;
                ctx->configs[i].type = fimd_win_types[i];
                ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
-                                       1 << ctx->pipe, &ctx->configs[i]);
+                                       &ctx->configs[i]);
                if (ret)
                        return ret;
        }
 
        exynos_plane = &ctx->planes[DEFAULT_WIN];
        ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
-                                          ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
-                                          &fimd_crtc_ops, ctx);
+                       EXYNOS_DISPLAY_TYPE_LCD, &fimd_crtc_ops, ctx);
        if (IS_ERR(ctx->crtc))
                return PTR_ERR(ctx->crtc);
 
@@ -1019,11 +1009,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
        if (is_drm_iommu_supported(drm_dev))
                fimd_clear_channels(ctx->crtc);
 
-       ret = drm_iommu_attach_device(drm_dev, dev);
-       if (ret)
-               priv->pipe--;
-
-       return ret;
+       return drm_iommu_attach_device(drm_dev, dev);
 }
 
 static void fimd_unbind(struct device *dev, struct device *master,
index c2f17f30afab2db811eed293d05662e90727d5d3..611b6fd65433d0a29a77c8549dcca47c0e4979a9 100644 (file)
@@ -273,14 +273,13 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
 }
 
 int exynos_plane_init(struct drm_device *dev,
-                     struct exynos_drm_plane *exynos_plane,
-                     unsigned int index, unsigned long possible_crtcs,
+                     struct exynos_drm_plane *exynos_plane, unsigned int index,
                      const struct exynos_drm_plane_config *config)
 {
        int err;
 
        err = drm_universal_plane_init(dev, &exynos_plane->base,
-                                      possible_crtcs,
+                                      1 << dev->mode_config.num_crtc,
                                       &exynos_plane_funcs,
                                       config->pixel_formats,
                                       config->num_pixel_formats,
index 9aafad164cdfc66552ddcd49f61318c8acbeb2bc..497047b196145e0a9ff0d8deb134059af350f0c2 100644 (file)
@@ -11,5 +11,4 @@
 
 int exynos_plane_init(struct drm_device *dev,
                      struct exynos_drm_plane *exynos_plane, unsigned int index,
-                     unsigned long possible_crtcs,
                      const struct exynos_drm_plane_config *config);
index ef86dbf1cc29b07a4f9c5378098f8f4dd9fdc078..cb8a728425371856dc9ef6c0b533574cc2038f96 100644 (file)
@@ -51,7 +51,6 @@ struct vidi_context {
        bool                            suspended;
        struct timer_list               timer;
        struct mutex                    lock;
-       int                             pipe;
 };
 
 static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e)
@@ -153,17 +152,6 @@ static void vidi_disable(struct exynos_drm_crtc *crtc)
        mutex_unlock(&ctx->lock);
 }
 
-static int vidi_ctx_initialize(struct vidi_context *ctx,
-                       struct drm_device *drm_dev)
-{
-       struct exynos_drm_private *priv = drm_dev->dev_private;
-
-       ctx->drm_dev = drm_dev;
-       ctx->pipe = priv->pipe++;
-
-       return 0;
-}
-
 static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
        .enable = vidi_enable,
        .disable = vidi_disable,
@@ -177,9 +165,6 @@ static void vidi_fake_vblank_timer(unsigned long arg)
 {
        struct vidi_context *ctx = (void *)arg;
 
-       if (ctx->pipe < 0)
-               return;
-
        if (drm_crtc_handle_vblank(&ctx->crtc->base))
                mod_timer(&ctx->timer,
                        jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1);
@@ -399,7 +384,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
        unsigned int i;
        int pipe, ret;
 
-       vidi_ctx_initialize(ctx, drm_dev);
+       ctx->drm_dev = drm_dev;
 
        plane_config.pixel_formats = formats;
        plane_config.num_pixel_formats = ARRAY_SIZE(formats);
@@ -409,15 +394,14 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
                plane_config.type = vidi_win_types[i];
 
                ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
-                                       1 << ctx->pipe, &plane_config);
+                                       &plane_config);
                if (ret)
                        return ret;
        }
 
        exynos_plane = &ctx->planes[DEFAULT_WIN];
        ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
-                                          ctx->pipe, EXYNOS_DISPLAY_TYPE_VIDI,
-                                          &vidi_crtc_ops, ctx);
+                       EXYNOS_DISPLAY_TYPE_VIDI, &vidi_crtc_ops, ctx);
        if (IS_ERR(ctx->crtc)) {
                DRM_ERROR("failed to create crtc.\n");
                return PTR_ERR(ctx->crtc);
index 1ff6ab6371e8e7aaa6bce6b1fe1dee64c9e08390..06bfbe400cf1d2ea23ec361a0fa1364a139ac43d 100644 (file)
@@ -1486,8 +1486,6 @@ static void hdmi_enable(struct drm_encoder *encoder)
 static void hdmi_disable(struct drm_encoder *encoder)
 {
        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
-       struct drm_crtc *crtc = encoder->crtc;
-       const struct drm_crtc_helper_funcs *funcs = NULL;
 
        if (!hdata->powered)
                return;
@@ -1498,16 +1496,11 @@ static void hdmi_disable(struct drm_encoder *encoder)
         * to disable TV Subsystem should be as following,
         *      VP -> Mixer -> HDMI
         *
-        * Below codes will try to disable Mixer and VP(if used)
-        * prior to disabling HDMI.
+        * To achieve such sequence HDMI is disabled together with HDMI PHY, via
+        * pipe clock callback.
         */
-       if (crtc)
-               funcs = crtc->helper_private;
-       if (funcs && funcs->disable)
-               (*funcs->disable)(crtc);
-
-       cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
        cancel_delayed_work(&hdata->hotplug_work);
+       cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
 
        hdmiphy_disable(hdata);
 }
index 25edb635a197621871d583e26b3d31d3717a82fa..6bed4f3ffcd6bd8592c51ee398a3ccdbe10355e1 100644 (file)
 #define MIXER_WIN_NR           3
 #define VP_DEFAULT_WIN         2
 
+/*
+ * Mixer color space conversion coefficient triplet.
+ * Used for CSC from RGB to YCbCr.
+ * Each coefficient is a 10-bit fixed point number with
+ * sign and no integer part, i.e.
+ * [0:8] = fractional part (representing a value y = x / 2^9)
+ * [9] = sign
+ * Negative values are encoded with two's complement.
+ */
+#define MXR_CSC_C(x) ((int)((x) * 512.0) & 0x3ff)
+#define MXR_CSC_CT(a0, a1, a2) \
+  ((MXR_CSC_C(a0) << 20) | (MXR_CSC_C(a1) << 10) | (MXR_CSC_C(a2) << 0))
+
+/* YCbCr value, used for mixer background color configuration. */
+#define MXR_YCBCR_VAL(y, cb, cr) (((y) << 16) | ((cb) << 8) | ((cr) << 0))
+
 /* The pixelformats that are natively supported by the mixer. */
 #define MXR_FORMAT_RGB565      4
 #define MXR_FORMAT_ARGB1555    5
@@ -99,7 +115,6 @@ struct mixer_context {
        struct drm_device       *drm_dev;
        struct exynos_drm_crtc  *crtc;
        struct exynos_drm_plane planes[MIXER_WIN_NR];
-       int                     pipe;
        unsigned long           flags;
 
        struct mixer_resources  mixer_res;
@@ -382,37 +397,24 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val;
 
-       if (height == 480) {
-               val = MXR_CFG_RGB601_0_255;
-       } else if (height == 576) {
+       switch (height) {
+       case 480:
+       case 576:
                val = MXR_CFG_RGB601_0_255;
-       } else if (height == 720) {
-               val = MXR_CFG_RGB709_16_235;
-               mixer_reg_write(res, MXR_CM_COEFF_Y,
-                               (1 << 30) | (94 << 20) | (314 << 10) |
-                               (32 << 0));
-               mixer_reg_write(res, MXR_CM_COEFF_CB,
-                               (972 << 20) | (851 << 10) | (225 << 0));
-               mixer_reg_write(res, MXR_CM_COEFF_CR,
-                               (225 << 20) | (820 << 10) | (1004 << 0));
-       } else if (height == 1080) {
-               val = MXR_CFG_RGB709_16_235;
-               mixer_reg_write(res, MXR_CM_COEFF_Y,
-                               (1 << 30) | (94 << 20) | (314 << 10) |
-                               (32 << 0));
-               mixer_reg_write(res, MXR_CM_COEFF_CB,
-                               (972 << 20) | (851 << 10) | (225 << 0));
-               mixer_reg_write(res, MXR_CM_COEFF_CR,
-                               (225 << 20) | (820 << 10) | (1004 << 0));
-       } else {
+               break;
+       case 720:
+       case 1080:
+       default:
                val = MXR_CFG_RGB709_16_235;
+               /* Configure the BT.709 CSC matrix for full range RGB. */
                mixer_reg_write(res, MXR_CM_COEFF_Y,
-                               (1 << 30) | (94 << 20) | (314 << 10) |
-                               (32 << 0));
+                       MXR_CSC_CT( 0.184,  0.614,  0.063) |
+                       MXR_CM_COEFF_RGB_FULL);
                mixer_reg_write(res, MXR_CM_COEFF_CB,
-                               (972 << 20) | (851 << 10) | (225 << 0));
+                       MXR_CSC_CT(-0.102, -0.338,  0.440));
                mixer_reg_write(res, MXR_CM_COEFF_CR,
-                               (225 << 20) | (820 << 10) | (1004 << 0));
+                       MXR_CSC_CT( 0.440, -0.399, -0.040));
+               break;
        }
 
        mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
@@ -729,10 +731,10 @@ static void mixer_win_reset(struct mixer_context *ctx)
        /* reset default layer priority */
        mixer_reg_write(res, MXR_LAYER_CFG, 0);
 
-       /* setting background color */
-       mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
-       mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
-       mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
+       /* set all background colors to RGB (0,0,0) */
+       mixer_reg_write(res, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
+       mixer_reg_write(res, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
+       mixer_reg_write(res, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
 
        if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
                /* configuration of Video Processor Registers */
@@ -900,7 +902,6 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
        priv = drm_dev->dev_private;
 
        mixer_ctx->drm_dev = drm_dev;
-       mixer_ctx->pipe = priv->pipe++;
 
        /* acquire resources: regs, irqs, clocks */
        ret = mixer_resources_init(mixer_ctx);
@@ -918,11 +919,7 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
                }
        }
 
-       ret = drm_iommu_attach_device(drm_dev, mixer_ctx->dev);
-       if (ret)
-               priv->pipe--;
-
-       return ret;
+       return drm_iommu_attach_device(drm_dev, mixer_ctx->dev);
 }
 
 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
@@ -1158,15 +1155,14 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
                        continue;
 
                ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
-                                       1 << ctx->pipe, &plane_configs[i]);
+                                       &plane_configs[i]);
                if (ret)
                        return ret;
        }
 
        exynos_plane = &ctx->planes[DEFAULT_WIN];
        ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
-                                          ctx->pipe, EXYNOS_DISPLAY_TYPE_HDMI,
-                                          &mixer_crtc_ops, ctx);
+                       EXYNOS_DISPLAY_TYPE_HDMI, &mixer_crtc_ops, ctx);
        if (IS_ERR(ctx->crtc)) {
                mixer_ctx_remove(ctx);
                ret = PTR_ERR(ctx->crtc);
index 7f22df5bf7070bb3a8b5af533302ad11e3a2bb47..c311f571bdf9ec522f938c5cc4891acf9c1026b2 100644 (file)
 #define MXR_INT_EN_VSYNC               (1 << 11)
 #define MXR_INT_EN_ALL                 (0x0f << 8)
 
-/* bit for MXR_INT_STATUS */
+/* bits for MXR_INT_STATUS */
 #define MXR_INT_CLEAR_VSYNC            (1 << 11)
 #define MXR_INT_STATUS_VSYNC           (1 << 0)
 
-/* bit for MXR_LAYER_CFG */
+/* bits for MXR_LAYER_CFG */
 #define MXR_LAYER_CFG_GRP1_VAL(x)      MXR_MASK_VAL(x, 11, 8)
 #define MXR_LAYER_CFG_GRP1_MASK                MXR_LAYER_CFG_GRP1_VAL(~0)
 #define MXR_LAYER_CFG_GRP0_VAL(x)      MXR_MASK_VAL(x, 7, 4)
 #define MXR_LAYER_CFG_VP_VAL(x)                MXR_MASK_VAL(x, 3, 0)
 #define MXR_LAYER_CFG_VP_MASK          MXR_LAYER_CFG_VP_VAL(~0)
 
+/* bits for MXR_CM_COEFF_Y */
+#define MXR_CM_COEFF_RGB_FULL          (1 << 30)
+
 #endif /* SAMSUNG_REGS_MIXER_H */
 
index 6b083d327e982c0c5deb7895ce6e7c6b1094c8a6..78957c9626f5880f302e1cf08fc5a44b2e40dcf3 100644 (file)
 #define WINCONx_ENWIN_F                        (1 << 0)
 
 /* SHADOWCON */
+#define SHADOWCON_PROTECT_MASK         GENMASK(14, 10)
 #define SHADOWCON_Wx_PROTECT(n)                (1 << (10 + (n)))
 
 /* VIDOSDxD */