Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2012 Russell King
0004  *  Rewritten from the dovefb driver, and Armada510 manuals.
0005  */
0006 
0007 #include <linux/clk.h>
0008 #include <linux/component.h>
0009 #include <linux/module.h>
0010 #include <linux/of_device.h>
0011 #include <linux/platform_device.h>
0012 
0013 #include <drm/drm_atomic.h>
0014 #include <drm/drm_atomic_helper.h>
0015 #include <drm/drm_plane_helper.h>
0016 #include <drm/drm_probe_helper.h>
0017 #include <drm/drm_vblank.h>
0018 
0019 #include "armada_crtc.h"
0020 #include "armada_drm.h"
0021 #include "armada_fb.h"
0022 #include "armada_gem.h"
0023 #include "armada_hw.h"
0024 #include "armada_plane.h"
0025 #include "armada_trace.h"
0026 
0027 /*
0028  * A note about interlacing.  Let's consider HDMI 1920x1080i.
0029  * The timing parameters we have from X are:
0030  *  Hact HsyA HsyI Htot  Vact VsyA VsyI Vtot
0031  *  1920 2448 2492 2640  1080 1084 1094 1125
0032  * Which get translated to:
0033  *  Hact HsyA HsyI Htot  Vact VsyA VsyI Vtot
0034  *  1920 2448 2492 2640   540  542  547  562
0035  *
0036  * This is how it is defined by CEA-861-D - line and pixel numbers are
0037  * referenced to the rising edge of VSYNC and HSYNC.  Total clocks per
0038  * line: 2640.  The odd frame, the first active line is at line 21, and
0039  * the even frame, the first active line is 584.
0040  *
0041  * LN:    560     561     562     563             567     568    569
0042  * DE:    ~~~|____________________________//__________________________
0043  * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
0044  * VSYNC: _________________________|~~~~~~//~~~~~~~~~~~~~~~|__________
0045  *  22 blanking lines.  VSYNC at 1320 (referenced to the HSYNC rising edge).
0046  *
0047  * LN:    1123   1124    1125      1               5       6      7
0048  * DE:    ~~~|____________________________//__________________________
0049  * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
0050  * VSYNC: ____________________|~~~~~~~~~~~//~~~~~~~~~~|_______________
0051  *  23 blanking lines
0052  *
0053  * The Armada LCD Controller line and pixel numbers are, like X timings,
0054  * referenced to the top left of the active frame.
0055  *
0056  * So, translating these to our LCD controller:
0057  *  Odd frame, 563 total lines, VSYNC at line 543-548, pixel 1128.
0058  *  Even frame, 562 total lines, VSYNC at line 542-547, pixel 2448.
0059  * Note: Vsync front porch remains constant!
0060  *
0061  * if (odd_frame) {
0062  *   vtotal = mode->crtc_vtotal + 1;
0063  *   vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay + 1;
0064  *   vhorizpos = mode->crtc_hsync_start - mode->crtc_htotal / 2
0065  * } else {
0066  *   vtotal = mode->crtc_vtotal;
0067  *   vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay;
0068  *   vhorizpos = mode->crtc_hsync_start;
0069  * }
0070  * vfrontporch = mode->crtc_vtotal - mode->crtc_vsync_end;
0071  *
0072  * So, we need to reprogram these registers on each vsync event:
0073  *  LCD_SPU_V_PORCH, LCD_SPU_ADV_REG, LCD_SPUT_V_H_TOTAL
0074  *
0075  * Note: we do not use the frame done interrupts because these appear
0076  * to happen too early, and lead to jitter on the display (presumably
0077  * they occur at the end of the last active line, before the vsync back
0078  * porch, which we're reprogramming.)
0079  */
0080 
0081 void
0082 armada_drm_crtc_update_regs(struct armada_crtc *dcrtc, struct armada_regs *regs)
0083 {
0084     while (regs->offset != ~0) {
0085         void __iomem *reg = dcrtc->base + regs->offset;
0086         uint32_t val;
0087 
0088         val = regs->mask;
0089         if (val != 0)
0090             val &= readl_relaxed(reg);
0091         writel_relaxed(val | regs->val, reg);
0092         ++regs;
0093     }
0094 }
0095 
0096 static void armada_drm_crtc_update(struct armada_crtc *dcrtc, bool enable)
0097 {
0098     uint32_t dumb_ctrl;
0099 
0100     dumb_ctrl = dcrtc->cfg_dumb_ctrl;
0101 
0102     if (enable)
0103         dumb_ctrl |= CFG_DUMB_ENA;
0104 
0105     /*
0106      * When the dumb interface isn't in DUMB24_RGB888_0 mode, it might
0107      * be using SPI or GPIO.  If we set this to DUMB_BLANK, we will
0108      * force LCD_D[23:0] to output blank color, overriding the GPIO or
0109      * SPI usage.  So leave it as-is unless in DUMB24_RGB888_0 mode.
0110      */
0111     if (!enable && (dumb_ctrl & DUMB_MASK) == DUMB24_RGB888_0) {
0112         dumb_ctrl &= ~DUMB_MASK;
0113         dumb_ctrl |= DUMB_BLANK;
0114     }
0115 
0116     armada_updatel(dumb_ctrl,
0117                ~(CFG_INV_CSYNC | CFG_INV_HSYNC | CFG_INV_VSYNC),
0118                dcrtc->base + LCD_SPU_DUMB_CTRL);
0119 }
0120 
0121 static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
0122 {
0123     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0124     struct drm_pending_vblank_event *event;
0125 
0126     /* If we have an event, we need vblank events enabled */
0127     event = xchg(&crtc->state->event, NULL);
0128     if (event) {
0129         WARN_ON(drm_crtc_vblank_get(crtc) != 0);
0130         dcrtc->event = event;
0131     }
0132 }
0133 
0134 static void armada_drm_update_gamma(struct drm_crtc *crtc)
0135 {
0136     struct drm_property_blob *blob = crtc->state->gamma_lut;
0137     void __iomem *base = drm_to_armada_crtc(crtc)->base;
0138     int i;
0139 
0140     if (blob) {
0141         struct drm_color_lut *lut = blob->data;
0142 
0143         armada_updatel(CFG_CSB_256x8, CFG_CSB_256x8 | CFG_PDWN256x8,
0144                    base + LCD_SPU_SRAM_PARA1);
0145 
0146         for (i = 0; i < 256; i++) {
0147             writel_relaxed(drm_color_lut_extract(lut[i].red, 8),
0148                        base + LCD_SPU_SRAM_WRDAT);
0149             writel_relaxed(i | SRAM_WRITE | SRAM_GAMMA_YR,
0150                        base + LCD_SPU_SRAM_CTRL);
0151             readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN);
0152             writel_relaxed(drm_color_lut_extract(lut[i].green, 8),
0153                        base + LCD_SPU_SRAM_WRDAT);
0154             writel_relaxed(i | SRAM_WRITE | SRAM_GAMMA_UG,
0155                        base + LCD_SPU_SRAM_CTRL);
0156             readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN);
0157             writel_relaxed(drm_color_lut_extract(lut[i].blue, 8),
0158                        base + LCD_SPU_SRAM_WRDAT);
0159             writel_relaxed(i | SRAM_WRITE | SRAM_GAMMA_VB,
0160                        base + LCD_SPU_SRAM_CTRL);
0161             readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN);
0162         }
0163         armada_updatel(CFG_GAMMA_ENA, CFG_GAMMA_ENA,
0164                    base + LCD_SPU_DMA_CTRL0);
0165     } else {
0166         armada_updatel(0, CFG_GAMMA_ENA, base + LCD_SPU_DMA_CTRL0);
0167         armada_updatel(CFG_PDWN256x8, CFG_CSB_256x8 | CFG_PDWN256x8,
0168                    base + LCD_SPU_SRAM_PARA1);
0169     }
0170 }
0171 
0172 static enum drm_mode_status armada_drm_crtc_mode_valid(struct drm_crtc *crtc,
0173     const struct drm_display_mode *mode)
0174 {
0175     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0176 
0177     if (mode->vscan > 1)
0178         return MODE_NO_VSCAN;
0179 
0180     if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0181         return MODE_NO_DBLESCAN;
0182 
0183     if (mode->flags & DRM_MODE_FLAG_HSKEW)
0184         return MODE_H_ILLEGAL;
0185 
0186     /* We can't do interlaced modes if we don't have the SPU_ADV_REG */
0187     if (!dcrtc->variant->has_spu_adv_reg &&
0188         mode->flags & DRM_MODE_FLAG_INTERLACE)
0189         return MODE_NO_INTERLACE;
0190 
0191     if (mode->flags & (DRM_MODE_FLAG_BCAST | DRM_MODE_FLAG_PIXMUX |
0192                DRM_MODE_FLAG_CLKDIV2))
0193         return MODE_BAD;
0194 
0195     return MODE_OK;
0196 }
0197 
0198 /* The mode_config.mutex will be held for this call */
0199 static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
0200     const struct drm_display_mode *mode, struct drm_display_mode *adj)
0201 {
0202     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0203     int ret;
0204 
0205     /*
0206      * Set CRTC modesetting parameters for the adjusted mode.  This is
0207      * applied after the connectors, bridges, and encoders have fixed up
0208      * this mode, as described above drm_atomic_helper_check_modeset().
0209      */
0210     drm_mode_set_crtcinfo(adj, CRTC_INTERLACE_HALVE_V);
0211 
0212     /*
0213      * Validate the adjusted mode in case an encoder/bridge has set
0214      * something we don't support.
0215      */
0216     if (armada_drm_crtc_mode_valid(crtc, adj) != MODE_OK)
0217         return false;
0218 
0219     /* Check whether the display mode is possible */
0220     ret = dcrtc->variant->compute_clock(dcrtc, adj, NULL);
0221     if (ret)
0222         return false;
0223 
0224     return true;
0225 }
0226 
0227 /* These are locked by dev->vbl_lock */
0228 static void armada_drm_crtc_disable_irq(struct armada_crtc *dcrtc, u32 mask)
0229 {
0230     if (dcrtc->irq_ena & mask) {
0231         dcrtc->irq_ena &= ~mask;
0232         writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
0233     }
0234 }
0235 
0236 static void armada_drm_crtc_enable_irq(struct armada_crtc *dcrtc, u32 mask)
0237 {
0238     if ((dcrtc->irq_ena & mask) != mask) {
0239         dcrtc->irq_ena |= mask;
0240         writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
0241         if (readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR) & mask)
0242             writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
0243     }
0244 }
0245 
0246 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
0247 {
0248     struct drm_pending_vblank_event *event;
0249     void __iomem *base = dcrtc->base;
0250 
0251     if (stat & DMA_FF_UNDERFLOW)
0252         DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
0253     if (stat & GRA_FF_UNDERFLOW)
0254         DRM_ERROR("graphics underflow on crtc %u\n", dcrtc->num);
0255 
0256     if (stat & VSYNC_IRQ)
0257         drm_crtc_handle_vblank(&dcrtc->crtc);
0258 
0259     spin_lock(&dcrtc->irq_lock);
0260     if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
0261         int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
0262         uint32_t val;
0263 
0264         writel_relaxed(dcrtc->v[i].spu_v_porch, base + LCD_SPU_V_PORCH);
0265         writel_relaxed(dcrtc->v[i].spu_v_h_total,
0266                    base + LCD_SPUT_V_H_TOTAL);
0267 
0268         val = readl_relaxed(base + LCD_SPU_ADV_REG);
0269         val &= ~(ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF | ADV_VSYNCOFFEN);
0270         val |= dcrtc->v[i].spu_adv_reg;
0271         writel_relaxed(val, base + LCD_SPU_ADV_REG);
0272     }
0273 
0274     if (stat & dcrtc->irq_ena & DUMB_FRAMEDONE) {
0275         if (dcrtc->update_pending) {
0276             armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
0277             dcrtc->update_pending = false;
0278         }
0279         if (dcrtc->cursor_update) {
0280             writel_relaxed(dcrtc->cursor_hw_pos,
0281                        base + LCD_SPU_HWC_OVSA_HPXL_VLN);
0282             writel_relaxed(dcrtc->cursor_hw_sz,
0283                        base + LCD_SPU_HWC_HPXL_VLN);
0284             armada_updatel(CFG_HWC_ENA,
0285                        CFG_HWC_ENA | CFG_HWC_1BITMOD |
0286                        CFG_HWC_1BITENA,
0287                        base + LCD_SPU_DMA_CTRL0);
0288             dcrtc->cursor_update = false;
0289         }
0290         armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
0291     }
0292     spin_unlock(&dcrtc->irq_lock);
0293 
0294     if (stat & VSYNC_IRQ && !dcrtc->update_pending) {
0295         event = xchg(&dcrtc->event, NULL);
0296         if (event) {
0297             spin_lock(&dcrtc->crtc.dev->event_lock);
0298             drm_crtc_send_vblank_event(&dcrtc->crtc, event);
0299             spin_unlock(&dcrtc->crtc.dev->event_lock);
0300             drm_crtc_vblank_put(&dcrtc->crtc);
0301         }
0302     }
0303 }
0304 
0305 static irqreturn_t armada_drm_irq(int irq, void *arg)
0306 {
0307     struct armada_crtc *dcrtc = arg;
0308     u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
0309 
0310     /*
0311      * Reading the ISR appears to clear bits provided CLEAN_SPU_IRQ_ISR
0312      * is set.  Writing has some other effect to acknowledge the IRQ -
0313      * without this, we only get a single IRQ.
0314      */
0315     writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
0316 
0317     trace_armada_drm_irq(&dcrtc->crtc, stat);
0318 
0319     /* Mask out those interrupts we haven't enabled */
0320     v = stat & dcrtc->irq_ena;
0321 
0322     if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
0323         armada_drm_crtc_irq(dcrtc, stat);
0324         return IRQ_HANDLED;
0325     }
0326     return IRQ_NONE;
0327 }
0328 
0329 /* The mode_config.mutex will be held for this call */
0330 static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
0331 {
0332     struct drm_display_mode *adj = &crtc->state->adjusted_mode;
0333     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0334     struct armada_regs regs[17];
0335     uint32_t lm, rm, tm, bm, val, sclk;
0336     unsigned long flags;
0337     unsigned i;
0338     bool interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
0339 
0340     i = 0;
0341     rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
0342     lm = adj->crtc_htotal - adj->crtc_hsync_end;
0343     bm = adj->crtc_vsync_start - adj->crtc_vdisplay;
0344     tm = adj->crtc_vtotal - adj->crtc_vsync_end;
0345 
0346     DRM_DEBUG_KMS("[CRTC:%d:%s] mode " DRM_MODE_FMT "\n",
0347               crtc->base.id, crtc->name, DRM_MODE_ARG(adj));
0348     DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm);
0349 
0350     /* Now compute the divider for real */
0351     dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
0352 
0353     armada_reg_queue_set(regs, i, sclk, LCD_CFG_SCLK_DIV);
0354 
0355     spin_lock_irqsave(&dcrtc->irq_lock, flags);
0356 
0357     dcrtc->interlaced = interlaced;
0358     /* Even interlaced/progressive frame */
0359     dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 |
0360                     adj->crtc_htotal;
0361     dcrtc->v[1].spu_v_porch = tm << 16 | bm;
0362     val = adj->crtc_hsync_start;
0363     dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN;
0364 
0365     if (interlaced) {
0366         /* Odd interlaced frame */
0367         val -= adj->crtc_htotal / 2;
0368         dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN;
0369         dcrtc->v[0].spu_v_h_total = dcrtc->v[1].spu_v_h_total +
0370                         (1 << 16);
0371         dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
0372     } else {
0373         dcrtc->v[0] = dcrtc->v[1];
0374     }
0375 
0376     val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
0377 
0378     armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE);
0379     armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH);
0380     armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH);
0381     armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
0382                LCD_SPUT_V_H_TOTAL);
0383 
0384     if (dcrtc->variant->has_spu_adv_reg)
0385         armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
0386                      ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
0387                      ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
0388 
0389     val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
0390     armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
0391 
0392     /*
0393      * The documentation doesn't indicate what the normal state of
0394      * the sync signals are.  Sebastian Hesselbart kindly probed
0395      * these signals on his board to determine their state.
0396      *
0397      * The non-inverted state of the sync signals is active high.
0398      * Setting these bits makes the appropriate signal active low.
0399      */
0400     val = 0;
0401     if (adj->flags & DRM_MODE_FLAG_NCSYNC)
0402         val |= CFG_INV_CSYNC;
0403     if (adj->flags & DRM_MODE_FLAG_NHSYNC)
0404         val |= CFG_INV_HSYNC;
0405     if (adj->flags & DRM_MODE_FLAG_NVSYNC)
0406         val |= CFG_INV_VSYNC;
0407     armada_reg_queue_mod(regs, i, val, CFG_INV_CSYNC | CFG_INV_HSYNC |
0408                  CFG_INV_VSYNC, LCD_SPU_DUMB_CTRL);
0409     armada_reg_queue_end(regs, i);
0410 
0411     armada_drm_crtc_update_regs(dcrtc, regs);
0412     spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
0413 }
0414 
0415 static int armada_drm_crtc_atomic_check(struct drm_crtc *crtc,
0416                     struct drm_atomic_state *state)
0417 {
0418     struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0419                                       crtc);
0420     DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0421 
0422     if (crtc_state->gamma_lut && drm_color_lut_size(crtc_state->gamma_lut) != 256)
0423         return -EINVAL;
0424 
0425     if (crtc_state->color_mgmt_changed)
0426         crtc_state->planes_changed = true;
0427 
0428     return 0;
0429 }
0430 
0431 static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc,
0432                      struct drm_atomic_state *state)
0433 {
0434     struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0435                                       crtc);
0436     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0437 
0438     DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0439 
0440     if (crtc_state->color_mgmt_changed)
0441         armada_drm_update_gamma(crtc);
0442 
0443     dcrtc->regs_idx = 0;
0444     dcrtc->regs = dcrtc->atomic_regs;
0445 }
0446 
0447 static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,
0448                      struct drm_atomic_state *state)
0449 {
0450     struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0451                                       crtc);
0452     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0453 
0454     DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0455 
0456     armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
0457 
0458     /*
0459      * If we aren't doing a full modeset, then we need to queue
0460      * the event here.
0461      */
0462     if (!drm_atomic_crtc_needs_modeset(crtc_state)) {
0463         dcrtc->update_pending = true;
0464         armada_drm_crtc_queue_state_event(crtc);
0465         spin_lock_irq(&dcrtc->irq_lock);
0466         armada_drm_crtc_enable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
0467         spin_unlock_irq(&dcrtc->irq_lock);
0468     } else {
0469         spin_lock_irq(&dcrtc->irq_lock);
0470         armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
0471         spin_unlock_irq(&dcrtc->irq_lock);
0472     }
0473 }
0474 
0475 static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
0476                        struct drm_atomic_state *state)
0477 {
0478     struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
0479                                      crtc);
0480     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0481     struct drm_pending_vblank_event *event;
0482 
0483     DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0484 
0485     if (old_state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
0486         drm_crtc_vblank_put(crtc);
0487 
0488     drm_crtc_vblank_off(crtc);
0489     armada_drm_crtc_update(dcrtc, false);
0490 
0491     if (!crtc->state->active) {
0492         /*
0493          * This modeset will be leaving the CRTC disabled, so
0494          * call the backend to disable upstream clocks etc.
0495          */
0496         if (dcrtc->variant->disable)
0497             dcrtc->variant->disable(dcrtc);
0498 
0499         /*
0500          * We will not receive any further vblank events.
0501          * Send the flip_done event manually.
0502          */
0503         event = crtc->state->event;
0504         crtc->state->event = NULL;
0505         if (event) {
0506             spin_lock_irq(&crtc->dev->event_lock);
0507             drm_crtc_send_vblank_event(crtc, event);
0508             spin_unlock_irq(&crtc->dev->event_lock);
0509         }
0510     }
0511 }
0512 
0513 static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc,
0514                       struct drm_atomic_state *state)
0515 {
0516     struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
0517                                      crtc);
0518     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0519 
0520     DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0521 
0522     if (!old_state->active) {
0523         /*
0524          * This modeset is enabling the CRTC after it having
0525          * been disabled.  Reverse the call to ->disable in
0526          * the atomic_disable().
0527          */
0528         if (dcrtc->variant->enable)
0529             dcrtc->variant->enable(dcrtc, &crtc->state->adjusted_mode);
0530     }
0531     armada_drm_crtc_update(dcrtc, true);
0532     drm_crtc_vblank_on(crtc);
0533 
0534     if (crtc->state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
0535         WARN_ON(drm_crtc_vblank_get(crtc));
0536 
0537     armada_drm_crtc_queue_state_event(crtc);
0538 }
0539 
0540 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
0541     .mode_valid = armada_drm_crtc_mode_valid,
0542     .mode_fixup = armada_drm_crtc_mode_fixup,
0543     .mode_set_nofb  = armada_drm_crtc_mode_set_nofb,
0544     .atomic_check   = armada_drm_crtc_atomic_check,
0545     .atomic_begin   = armada_drm_crtc_atomic_begin,
0546     .atomic_flush   = armada_drm_crtc_atomic_flush,
0547     .atomic_disable = armada_drm_crtc_atomic_disable,
0548     .atomic_enable  = armada_drm_crtc_atomic_enable,
0549 };
0550 
0551 static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix,
0552     unsigned stride, unsigned width, unsigned height)
0553 {
0554     uint32_t addr;
0555     unsigned y;
0556 
0557     addr = SRAM_HWC32_RAM1;
0558     for (y = 0; y < height; y++) {
0559         uint32_t *p = &pix[y * stride];
0560         unsigned x;
0561 
0562         for (x = 0; x < width; x++, p++) {
0563             uint32_t val = *p;
0564 
0565             /*
0566              * In "ARGB888" (HWC32) mode, writing to the SRAM
0567              * requires these bits to contain:
0568              * 31:24 = alpha 23:16 = blue 15:8 = green 7:0 = red
0569              * So, it's actually ABGR8888.  This is independent
0570              * of the SWAPRB bits in DMA control register 0.
0571              */
0572             val = (val & 0xff00ff00) |
0573                   (val & 0x000000ff) << 16 |
0574                   (val & 0x00ff0000) >> 16;
0575 
0576             writel_relaxed(val,
0577                        base + LCD_SPU_SRAM_WRDAT);
0578             writel_relaxed(addr | SRAM_WRITE,
0579                        base + LCD_SPU_SRAM_CTRL);
0580             readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN);
0581             addr += 1;
0582             if ((addr & 0x00ff) == 0)
0583                 addr += 0xf00;
0584             if ((addr & 0x30ff) == 0)
0585                 addr = SRAM_HWC32_RAM2;
0586         }
0587     }
0588 }
0589 
0590 static void armada_drm_crtc_cursor_tran(void __iomem *base)
0591 {
0592     unsigned addr;
0593 
0594     for (addr = 0; addr < 256; addr++) {
0595         /* write the default value */
0596         writel_relaxed(0x55555555, base + LCD_SPU_SRAM_WRDAT);
0597         writel_relaxed(addr | SRAM_WRITE | SRAM_HWC32_TRAN,
0598                    base + LCD_SPU_SRAM_CTRL);
0599     }
0600 }
0601 
0602 static int armada_drm_crtc_cursor_update(struct armada_crtc *dcrtc, bool reload)
0603 {
0604     uint32_t xoff, xscr, w = dcrtc->cursor_w, s;
0605     uint32_t yoff, yscr, h = dcrtc->cursor_h;
0606     uint32_t para1;
0607 
0608     /*
0609      * Calculate the visible width and height of the cursor,
0610      * screen position, and the position in the cursor bitmap.
0611      */
0612     if (dcrtc->cursor_x < 0) {
0613         xoff = -dcrtc->cursor_x;
0614         xscr = 0;
0615         w -= min(xoff, w);
0616     } else if (dcrtc->cursor_x + w > dcrtc->crtc.mode.hdisplay) {
0617         xoff = 0;
0618         xscr = dcrtc->cursor_x;
0619         w = max_t(int, dcrtc->crtc.mode.hdisplay - dcrtc->cursor_x, 0);
0620     } else {
0621         xoff = 0;
0622         xscr = dcrtc->cursor_x;
0623     }
0624 
0625     if (dcrtc->cursor_y < 0) {
0626         yoff = -dcrtc->cursor_y;
0627         yscr = 0;
0628         h -= min(yoff, h);
0629     } else if (dcrtc->cursor_y + h > dcrtc->crtc.mode.vdisplay) {
0630         yoff = 0;
0631         yscr = dcrtc->cursor_y;
0632         h = max_t(int, dcrtc->crtc.mode.vdisplay - dcrtc->cursor_y, 0);
0633     } else {
0634         yoff = 0;
0635         yscr = dcrtc->cursor_y;
0636     }
0637 
0638     /* On interlaced modes, the vertical cursor size must be halved */
0639     s = dcrtc->cursor_w;
0640     if (dcrtc->interlaced) {
0641         s *= 2;
0642         yscr /= 2;
0643         h /= 2;
0644     }
0645 
0646     if (!dcrtc->cursor_obj || !h || !w) {
0647         spin_lock_irq(&dcrtc->irq_lock);
0648         dcrtc->cursor_update = false;
0649         armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
0650         spin_unlock_irq(&dcrtc->irq_lock);
0651         return 0;
0652     }
0653 
0654     spin_lock_irq(&dcrtc->irq_lock);
0655     para1 = readl_relaxed(dcrtc->base + LCD_SPU_SRAM_PARA1);
0656     armada_updatel(CFG_CSB_256x32, CFG_CSB_256x32 | CFG_PDWN256x32,
0657                dcrtc->base + LCD_SPU_SRAM_PARA1);
0658     spin_unlock_irq(&dcrtc->irq_lock);
0659 
0660     /*
0661      * Initialize the transparency if the SRAM was powered down.
0662      * We must also reload the cursor data as well.
0663      */
0664     if (!(para1 & CFG_CSB_256x32)) {
0665         armada_drm_crtc_cursor_tran(dcrtc->base);
0666         reload = true;
0667     }
0668 
0669     if (dcrtc->cursor_hw_sz != (h << 16 | w)) {
0670         spin_lock_irq(&dcrtc->irq_lock);
0671         dcrtc->cursor_update = false;
0672         armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
0673         spin_unlock_irq(&dcrtc->irq_lock);
0674         reload = true;
0675     }
0676     if (reload) {
0677         struct armada_gem_object *obj = dcrtc->cursor_obj;
0678         uint32_t *pix;
0679         /* Set the top-left corner of the cursor image */
0680         pix = obj->addr;
0681         pix += yoff * s + xoff;
0682         armada_load_cursor_argb(dcrtc->base, pix, s, w, h);
0683     }
0684 
0685     /* Reload the cursor position, size and enable in the IRQ handler */
0686     spin_lock_irq(&dcrtc->irq_lock);
0687     dcrtc->cursor_hw_pos = yscr << 16 | xscr;
0688     dcrtc->cursor_hw_sz = h << 16 | w;
0689     dcrtc->cursor_update = true;
0690     armada_drm_crtc_enable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
0691     spin_unlock_irq(&dcrtc->irq_lock);
0692 
0693     return 0;
0694 }
0695 
0696 static void cursor_update(void *data)
0697 {
0698     armada_drm_crtc_cursor_update(data, true);
0699 }
0700 
0701 static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
0702     struct drm_file *file, uint32_t handle, uint32_t w, uint32_t h)
0703 {
0704     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0705     struct armada_gem_object *obj = NULL;
0706     int ret;
0707 
0708     /* If no cursor support, replicate drm's return value */
0709     if (!dcrtc->variant->has_spu_adv_reg)
0710         return -ENXIO;
0711 
0712     if (handle && w > 0 && h > 0) {
0713         /* maximum size is 64x32 or 32x64 */
0714         if (w > 64 || h > 64 || (w > 32 && h > 32))
0715             return -ENOMEM;
0716 
0717         obj = armada_gem_object_lookup(file, handle);
0718         if (!obj)
0719             return -ENOENT;
0720 
0721         /* Must be a kernel-mapped object */
0722         if (!obj->addr) {
0723             drm_gem_object_put(&obj->obj);
0724             return -EINVAL;
0725         }
0726 
0727         if (obj->obj.size < w * h * 4) {
0728             DRM_ERROR("buffer is too small\n");
0729             drm_gem_object_put(&obj->obj);
0730             return -ENOMEM;
0731         }
0732     }
0733 
0734     if (dcrtc->cursor_obj) {
0735         dcrtc->cursor_obj->update = NULL;
0736         dcrtc->cursor_obj->update_data = NULL;
0737         drm_gem_object_put(&dcrtc->cursor_obj->obj);
0738     }
0739     dcrtc->cursor_obj = obj;
0740     dcrtc->cursor_w = w;
0741     dcrtc->cursor_h = h;
0742     ret = armada_drm_crtc_cursor_update(dcrtc, true);
0743     if (obj) {
0744         obj->update_data = dcrtc;
0745         obj->update = cursor_update;
0746     }
0747 
0748     return ret;
0749 }
0750 
0751 static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
0752 {
0753     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0754     int ret;
0755 
0756     /* If no cursor support, replicate drm's return value */
0757     if (!dcrtc->variant->has_spu_adv_reg)
0758         return -EFAULT;
0759 
0760     dcrtc->cursor_x = x;
0761     dcrtc->cursor_y = y;
0762     ret = armada_drm_crtc_cursor_update(dcrtc, false);
0763 
0764     return ret;
0765 }
0766 
0767 static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
0768 {
0769     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0770     struct armada_private *priv = drm_to_armada_dev(crtc->dev);
0771 
0772     if (dcrtc->cursor_obj)
0773         drm_gem_object_put(&dcrtc->cursor_obj->obj);
0774 
0775     priv->dcrtc[dcrtc->num] = NULL;
0776     drm_crtc_cleanup(&dcrtc->crtc);
0777 
0778     if (dcrtc->variant->disable)
0779         dcrtc->variant->disable(dcrtc);
0780 
0781     writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
0782 
0783     of_node_put(dcrtc->crtc.port);
0784 
0785     kfree(dcrtc);
0786 }
0787 
0788 static int armada_drm_crtc_late_register(struct drm_crtc *crtc)
0789 {
0790     if (IS_ENABLED(CONFIG_DEBUG_FS))
0791         armada_drm_crtc_debugfs_init(drm_to_armada_crtc(crtc));
0792 
0793     return 0;
0794 }
0795 
0796 /* These are called under the vbl_lock. */
0797 static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc)
0798 {
0799     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0800     unsigned long flags;
0801 
0802     spin_lock_irqsave(&dcrtc->irq_lock, flags);
0803     armada_drm_crtc_enable_irq(dcrtc, VSYNC_IRQ_ENA);
0804     spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
0805     return 0;
0806 }
0807 
0808 static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc)
0809 {
0810     struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
0811     unsigned long flags;
0812 
0813     spin_lock_irqsave(&dcrtc->irq_lock, flags);
0814     armada_drm_crtc_disable_irq(dcrtc, VSYNC_IRQ_ENA);
0815     spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
0816 }
0817 
0818 static const struct drm_crtc_funcs armada_crtc_funcs = {
0819     .reset      = drm_atomic_helper_crtc_reset,
0820     .cursor_set = armada_drm_crtc_cursor_set,
0821     .cursor_move    = armada_drm_crtc_cursor_move,
0822     .destroy    = armada_drm_crtc_destroy,
0823     .set_config = drm_atomic_helper_set_config,
0824     .page_flip  = drm_atomic_helper_page_flip,
0825     .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
0826     .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
0827     .late_register  = armada_drm_crtc_late_register,
0828     .enable_vblank  = armada_drm_crtc_enable_vblank,
0829     .disable_vblank = armada_drm_crtc_disable_vblank,
0830 };
0831 
0832 int armada_crtc_select_clock(struct armada_crtc *dcrtc,
0833                  struct armada_clk_result *res,
0834                  const struct armada_clocking_params *params,
0835                  struct clk *clks[], size_t num_clks,
0836                  unsigned long desired_khz)
0837 {
0838     unsigned long desired_hz = desired_khz * 1000;
0839     unsigned long desired_clk_hz;   // requested clk input
0840     unsigned long real_clk_hz;  // actual clk input
0841     unsigned long real_hz;      // actual pixel clk
0842     unsigned long permillage;
0843     struct clk *clk;
0844     u32 div;
0845     int i;
0846 
0847     DRM_DEBUG_KMS("[CRTC:%u:%s] desired clock=%luHz\n",
0848               dcrtc->crtc.base.id, dcrtc->crtc.name, desired_hz);
0849 
0850     for (i = 0; i < num_clks; i++) {
0851         clk = clks[i];
0852         if (!clk)
0853             continue;
0854 
0855         if (params->settable & BIT(i)) {
0856             real_clk_hz = clk_round_rate(clk, desired_hz);
0857             desired_clk_hz = desired_hz;
0858         } else {
0859             real_clk_hz = clk_get_rate(clk);
0860             desired_clk_hz = real_clk_hz;
0861         }
0862 
0863         /* If the clock can do exactly the desired rate, we're done */
0864         if (real_clk_hz == desired_hz) {
0865             real_hz = real_clk_hz;
0866             div = 1;
0867             goto found;
0868         }
0869 
0870         /* Calculate the divider - if invalid, we can't do this rate */
0871         div = DIV_ROUND_CLOSEST(real_clk_hz, desired_hz);
0872         if (div == 0 || div > params->div_max)
0873             continue;
0874 
0875         /* Calculate the actual rate - HDMI requires -0.6%..+0.5% */
0876         real_hz = DIV_ROUND_CLOSEST(real_clk_hz, div);
0877 
0878         DRM_DEBUG_KMS("[CRTC:%u:%s] clk=%u %luHz div=%u real=%luHz\n",
0879             dcrtc->crtc.base.id, dcrtc->crtc.name,
0880             i, real_clk_hz, div, real_hz);
0881 
0882         /* Avoid repeated division */
0883         if (real_hz < desired_hz) {
0884             permillage = real_hz / desired_khz;
0885             if (permillage < params->permillage_min)
0886                 continue;
0887         } else {
0888             permillage = DIV_ROUND_UP(real_hz, desired_khz);
0889             if (permillage > params->permillage_max)
0890                 continue;
0891         }
0892         goto found;
0893     }
0894 
0895     return -ERANGE;
0896 
0897 found:
0898     DRM_DEBUG_KMS("[CRTC:%u:%s] selected clk=%u %luHz div=%u real=%luHz\n",
0899         dcrtc->crtc.base.id, dcrtc->crtc.name,
0900         i, real_clk_hz, div, real_hz);
0901 
0902     res->desired_clk_hz = desired_clk_hz;
0903     res->clk = clk;
0904     res->div = div;
0905 
0906     return i;
0907 }
0908 
0909 static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
0910     struct resource *res, int irq, const struct armada_variant *variant,
0911     struct device_node *port)
0912 {
0913     struct armada_private *priv = drm_to_armada_dev(drm);
0914     struct armada_crtc *dcrtc;
0915     struct drm_plane *primary;
0916     void __iomem *base;
0917     int ret;
0918 
0919     base = devm_ioremap_resource(dev, res);
0920     if (IS_ERR(base))
0921         return PTR_ERR(base);
0922 
0923     dcrtc = kzalloc(sizeof(*dcrtc), GFP_KERNEL);
0924     if (!dcrtc) {
0925         DRM_ERROR("failed to allocate Armada crtc\n");
0926         return -ENOMEM;
0927     }
0928 
0929     if (dev != drm->dev)
0930         dev_set_drvdata(dev, dcrtc);
0931 
0932     dcrtc->variant = variant;
0933     dcrtc->base = base;
0934     dcrtc->num = drm->mode_config.num_crtc;
0935     dcrtc->cfg_dumb_ctrl = DUMB24_RGB888_0;
0936     dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
0937     spin_lock_init(&dcrtc->irq_lock);
0938     dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
0939 
0940     /* Initialize some registers which we don't otherwise set */
0941     writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
0942     writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_BLANKCOLOR);
0943     writel_relaxed(dcrtc->spu_iopad_ctrl,
0944                dcrtc->base + LCD_SPU_IOPAD_CONTROL);
0945     writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_SRAM_PARA0);
0946     writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
0947                CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
0948                CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
0949     writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
0950     writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
0951     readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
0952     writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
0953 
0954     ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
0955                    dcrtc);
0956     if (ret < 0)
0957         goto err_crtc;
0958 
0959     if (dcrtc->variant->init) {
0960         ret = dcrtc->variant->init(dcrtc, dev);
0961         if (ret)
0962             goto err_crtc;
0963     }
0964 
0965     /* Ensure AXI pipeline is enabled */
0966     armada_updatel(CFG_ARBFAST_ENA, 0, dcrtc->base + LCD_SPU_DMA_CTRL0);
0967 
0968     priv->dcrtc[dcrtc->num] = dcrtc;
0969 
0970     dcrtc->crtc.port = port;
0971 
0972     primary = kzalloc(sizeof(*primary), GFP_KERNEL);
0973     if (!primary) {
0974         ret = -ENOMEM;
0975         goto err_crtc;
0976     }
0977 
0978     ret = armada_drm_primary_plane_init(drm, primary);
0979     if (ret) {
0980         kfree(primary);
0981         goto err_crtc;
0982     }
0983 
0984     ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, primary, NULL,
0985                     &armada_crtc_funcs, NULL);
0986     if (ret)
0987         goto err_crtc_init;
0988 
0989     drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
0990 
0991     ret = drm_mode_crtc_set_gamma_size(&dcrtc->crtc, 256);
0992     if (ret)
0993         return ret;
0994 
0995     drm_crtc_enable_color_mgmt(&dcrtc->crtc, 0, false, 256);
0996 
0997     return armada_overlay_plane_create(drm, 1 << dcrtc->num);
0998 
0999 err_crtc_init:
1000     primary->funcs->destroy(primary);
1001 err_crtc:
1002     kfree(dcrtc);
1003 
1004     return ret;
1005 }
1006 
1007 static int
1008 armada_lcd_bind(struct device *dev, struct device *master, void *data)
1009 {
1010     struct platform_device *pdev = to_platform_device(dev);
1011     struct drm_device *drm = data;
1012     struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1013     int irq = platform_get_irq(pdev, 0);
1014     const struct armada_variant *variant;
1015     struct device_node *port = NULL;
1016 
1017     if (irq < 0)
1018         return irq;
1019 
1020     if (!dev->of_node) {
1021         const struct platform_device_id *id;
1022 
1023         id = platform_get_device_id(pdev);
1024         if (!id)
1025             return -ENXIO;
1026 
1027         variant = (const struct armada_variant *)id->driver_data;
1028     } else {
1029         const struct of_device_id *match;
1030         struct device_node *np, *parent = dev->of_node;
1031 
1032         match = of_match_device(dev->driver->of_match_table, dev);
1033         if (!match)
1034             return -ENXIO;
1035 
1036         np = of_get_child_by_name(parent, "ports");
1037         if (np)
1038             parent = np;
1039         port = of_get_child_by_name(parent, "port");
1040         of_node_put(np);
1041         if (!port) {
1042             dev_err(dev, "no port node found in %pOF\n", parent);
1043             return -ENXIO;
1044         }
1045 
1046         variant = match->data;
1047     }
1048 
1049     return armada_drm_crtc_create(drm, dev, res, irq, variant, port);
1050 }
1051 
1052 static void
1053 armada_lcd_unbind(struct device *dev, struct device *master, void *data)
1054 {
1055     struct armada_crtc *dcrtc = dev_get_drvdata(dev);
1056 
1057     armada_drm_crtc_destroy(&dcrtc->crtc);
1058 }
1059 
1060 static const struct component_ops armada_lcd_ops = {
1061     .bind = armada_lcd_bind,
1062     .unbind = armada_lcd_unbind,
1063 };
1064 
1065 static int armada_lcd_probe(struct platform_device *pdev)
1066 {
1067     return component_add(&pdev->dev, &armada_lcd_ops);
1068 }
1069 
1070 static int armada_lcd_remove(struct platform_device *pdev)
1071 {
1072     component_del(&pdev->dev, &armada_lcd_ops);
1073     return 0;
1074 }
1075 
1076 static const struct of_device_id armada_lcd_of_match[] = {
1077     {
1078         .compatible = "marvell,dove-lcd",
1079         .data       = &armada510_ops,
1080     },
1081     {}
1082 };
1083 MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
1084 
1085 static const struct platform_device_id armada_lcd_platform_ids[] = {
1086     {
1087         .name       = "armada-lcd",
1088         .driver_data    = (unsigned long)&armada510_ops,
1089     }, {
1090         .name       = "armada-510-lcd",
1091         .driver_data    = (unsigned long)&armada510_ops,
1092     },
1093     { },
1094 };
1095 MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids);
1096 
1097 struct platform_driver armada_lcd_platform_driver = {
1098     .probe  = armada_lcd_probe,
1099     .remove = armada_lcd_remove,
1100     .driver = {
1101         .name   = "armada-lcd",
1102         .owner  =  THIS_MODULE,
1103         .of_match_table = armada_lcd_of_match,
1104     },
1105     .id_table = armada_lcd_platform_ids,
1106 };