linux/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Ingenic JZ47xx KMS driver
   4//
   5// Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
   6
   7#include "ingenic-drm.h"
   8
   9#include <linux/bitfield.h>
  10#include <linux/component.h>
  11#include <linux/clk.h>
  12#include <linux/dma-mapping.h>
  13#include <linux/io.h>
  14#include <linux/media-bus-format.h>
  15#include <linux/module.h>
  16#include <linux/mutex.h>
  17#include <linux/of_device.h>
  18#include <linux/of_reserved_mem.h>
  19#include <linux/platform_device.h>
  20#include <linux/pm.h>
  21#include <linux/regmap.h>
  22
  23#include <drm/drm_atomic.h>
  24#include <drm/drm_atomic_helper.h>
  25#include <drm/drm_bridge.h>
  26#include <drm/drm_bridge_connector.h>
  27#include <drm/drm_color_mgmt.h>
  28#include <drm/drm_crtc.h>
  29#include <drm/drm_crtc_helper.h>
  30#include <drm/drm_damage_helper.h>
  31#include <drm/drm_drv.h>
  32#include <drm/drm_encoder.h>
  33#include <drm/drm_gem_cma_helper.h>
  34#include <drm/drm_fb_cma_helper.h>
  35#include <drm/drm_fb_helper.h>
  36#include <drm/drm_fourcc.h>
  37#include <drm/drm_framebuffer.h>
  38#include <drm/drm_gem_atomic_helper.h>
  39#include <drm/drm_gem_framebuffer_helper.h>
  40#include <drm/drm_managed.h>
  41#include <drm/drm_of.h>
  42#include <drm/drm_panel.h>
  43#include <drm/drm_plane.h>
  44#include <drm/drm_plane_helper.h>
  45#include <drm/drm_probe_helper.h>
  46#include <drm/drm_vblank.h>
  47
  48#define HWDESC_PALETTE 2
  49
  50struct ingenic_dma_hwdesc {
  51        u32 next;
  52        u32 addr;
  53        u32 id;
  54        u32 cmd;
  55        /* extended hw descriptor for jz4780 */
  56        u32 offsize;
  57        u32 pagewidth;
  58        u32 cpos;
  59        u32 dessize;
  60} __aligned(16);
  61
  62struct ingenic_dma_hwdescs {
  63        struct ingenic_dma_hwdesc hwdesc[3];
  64        u16 palette[256] __aligned(16);
  65};
  66
  67struct jz_soc_info {
  68        bool needs_dev_clk;
  69        bool has_osd;
  70        bool has_alpha;
  71        bool map_noncoherent;
  72        bool use_extended_hwdesc;
  73        bool plane_f0_not_working;
  74        u32 max_burst;
  75        unsigned int max_width, max_height;
  76        const u32 *formats_f0, *formats_f1;
  77        unsigned int num_formats_f0, num_formats_f1;
  78};
  79
  80struct ingenic_drm_private_state {
  81        struct drm_private_state base;
  82        bool use_palette;
  83};
  84
  85struct ingenic_drm {
  86        struct drm_device drm;
  87        /*
  88         * f1 (aka. foreground1) is our primary plane, on top of which
  89         * f0 (aka. foreground0) can be overlayed. Z-order is fixed in
  90         * hardware and cannot be changed.
  91         */
  92        struct drm_plane f0, f1, *ipu_plane;
  93        struct drm_crtc crtc;
  94
  95        struct device *dev;
  96        struct regmap *map;
  97        struct clk *lcd_clk, *pix_clk;
  98        const struct jz_soc_info *soc_info;
  99
 100        struct ingenic_dma_hwdescs *dma_hwdescs;
 101        dma_addr_t dma_hwdescs_phys;
 102
 103        bool panel_is_sharp;
 104        bool no_vblank;
 105
 106        /*
 107         * clk_mutex is used to synchronize the pixel clock rate update with
 108         * the VBLANK. When the pixel clock's parent clock needs to be updated,
 109         * clock_nb's notifier function will lock the mutex, then wait until the
 110         * next VBLANK. At that point, the parent clock's rate can be updated,
 111         * and the mutex is then unlocked. If an atomic commit happens in the
 112         * meantime, it will lock on the mutex, effectively waiting until the
 113         * clock update process finishes. Finally, the pixel clock's rate will
 114         * be recomputed when the mutex has been released, in the pending atomic
 115         * commit, or a future one.
 116         */
 117        struct mutex clk_mutex;
 118        bool update_clk_rate;
 119        struct notifier_block clock_nb;
 120
 121        struct drm_private_obj private_obj;
 122};
 123
 124struct ingenic_drm_bridge {
 125        struct drm_encoder encoder;
 126        struct drm_bridge bridge, *next_bridge;
 127
 128        struct drm_bus_cfg bus_cfg;
 129};
 130
 131static inline struct ingenic_drm_bridge *
 132to_ingenic_drm_bridge(struct drm_encoder *encoder)
 133{
 134        return container_of(encoder, struct ingenic_drm_bridge, encoder);
 135}
 136
 137static inline struct ingenic_drm_private_state *
 138to_ingenic_drm_priv_state(struct drm_private_state *state)
 139{
 140        return container_of(state, struct ingenic_drm_private_state, base);
 141}
 142
 143static struct ingenic_drm_private_state *
 144ingenic_drm_get_priv_state(struct ingenic_drm *priv, struct drm_atomic_state *state)
 145{
 146        struct drm_private_state *priv_state;
 147
 148        priv_state = drm_atomic_get_private_obj_state(state, &priv->private_obj);
 149        if (IS_ERR(priv_state))
 150                return ERR_CAST(priv_state);
 151
 152        return to_ingenic_drm_priv_state(priv_state);
 153}
 154
 155static struct ingenic_drm_private_state *
 156ingenic_drm_get_new_priv_state(struct ingenic_drm *priv, struct drm_atomic_state *state)
 157{
 158        struct drm_private_state *priv_state;
 159
 160        priv_state = drm_atomic_get_new_private_obj_state(state, &priv->private_obj);
 161        if (!priv_state)
 162                return NULL;
 163
 164        return to_ingenic_drm_priv_state(priv_state);
 165}
 166
 167static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
 168{
 169        switch (reg) {
 170        case JZ_REG_LCD_IID:
 171        case JZ_REG_LCD_SA0:
 172        case JZ_REG_LCD_FID0:
 173        case JZ_REG_LCD_CMD0:
 174        case JZ_REG_LCD_SA1:
 175        case JZ_REG_LCD_FID1:
 176        case JZ_REG_LCD_CMD1:
 177                return false;
 178        default:
 179                return true;
 180        }
 181}
 182
 183static const struct regmap_config ingenic_drm_regmap_config = {
 184        .reg_bits = 32,
 185        .val_bits = 32,
 186        .reg_stride = 4,
 187
 188        .writeable_reg = ingenic_drm_writeable_reg,
 189};
 190
 191static inline struct ingenic_drm *drm_device_get_priv(struct drm_device *drm)
 192{
 193        return container_of(drm, struct ingenic_drm, drm);
 194}
 195
 196static inline struct ingenic_drm *drm_crtc_get_priv(struct drm_crtc *crtc)
 197{
 198        return container_of(crtc, struct ingenic_drm, crtc);
 199}
 200
 201static inline struct ingenic_drm *drm_nb_get_priv(struct notifier_block *nb)
 202{
 203        return container_of(nb, struct ingenic_drm, clock_nb);
 204}
 205
 206static inline dma_addr_t dma_hwdesc_addr(const struct ingenic_drm *priv,
 207                                         unsigned int idx)
 208{
 209        u32 offset = offsetof(struct ingenic_dma_hwdescs, hwdesc[idx]);
 210
 211        return priv->dma_hwdescs_phys + offset;
 212}
 213
 214static int ingenic_drm_update_pixclk(struct notifier_block *nb,
 215                                     unsigned long action,
 216                                     void *data)
 217{
 218        struct ingenic_drm *priv = drm_nb_get_priv(nb);
 219
 220        switch (action) {
 221        case PRE_RATE_CHANGE:
 222                mutex_lock(&priv->clk_mutex);
 223                priv->update_clk_rate = true;
 224                drm_crtc_wait_one_vblank(&priv->crtc);
 225                return NOTIFY_OK;
 226        default:
 227                mutex_unlock(&priv->clk_mutex);
 228                return NOTIFY_OK;
 229        }
 230}
 231
 232static void ingenic_drm_bridge_atomic_enable(struct drm_bridge *bridge,
 233                                             struct drm_bridge_state *old_bridge_state)
 234{
 235        struct ingenic_drm *priv = drm_device_get_priv(bridge->dev);
 236
 237        regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
 238
 239        regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
 240                           JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE,
 241                           JZ_LCD_CTRL_ENABLE);
 242}
 243
 244static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 245                                           struct drm_atomic_state *state)
 246{
 247        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 248        struct ingenic_drm_private_state *priv_state;
 249        unsigned int next_id;
 250
 251        priv_state = ingenic_drm_get_priv_state(priv, state);
 252        if (WARN_ON(IS_ERR(priv_state)))
 253                return;
 254
 255        /* Set addresses of our DMA descriptor chains */
 256        next_id = priv_state->use_palette ? HWDESC_PALETTE : 0;
 257        regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, next_id));
 258        regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1));
 259
 260        drm_crtc_vblank_on(crtc);
 261}
 262
 263static void ingenic_drm_bridge_atomic_disable(struct drm_bridge *bridge,
 264                                              struct drm_bridge_state *old_bridge_state)
 265{
 266        struct ingenic_drm *priv = drm_device_get_priv(bridge->dev);
 267        unsigned int var;
 268
 269        regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
 270                           JZ_LCD_CTRL_DISABLE, JZ_LCD_CTRL_DISABLE);
 271
 272        regmap_read_poll_timeout(priv->map, JZ_REG_LCD_STATE, var,
 273                                 var & JZ_LCD_STATE_DISABLED,
 274                                 1000, 0);
 275}
 276
 277static void ingenic_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 278                                            struct drm_atomic_state *state)
 279{
 280        drm_crtc_vblank_off(crtc);
 281}
 282
 283static void ingenic_drm_crtc_update_timings(struct ingenic_drm *priv,
 284                                            struct drm_display_mode *mode)
 285{
 286        unsigned int vpe, vds, vde, vt, hpe, hds, hde, ht;
 287
 288        vpe = mode->crtc_vsync_end - mode->crtc_vsync_start;
 289        vds = mode->crtc_vtotal - mode->crtc_vsync_start;
 290        vde = vds + mode->crtc_vdisplay;
 291        vt = vde + mode->crtc_vsync_start - mode->crtc_vdisplay;
 292
 293        hpe = mode->crtc_hsync_end - mode->crtc_hsync_start;
 294        hds = mode->crtc_htotal - mode->crtc_hsync_start;
 295        hde = hds + mode->crtc_hdisplay;
 296        ht = hde + mode->crtc_hsync_start - mode->crtc_hdisplay;
 297
 298        regmap_write(priv->map, JZ_REG_LCD_VSYNC,
 299                     0 << JZ_LCD_VSYNC_VPS_OFFSET |
 300                     vpe << JZ_LCD_VSYNC_VPE_OFFSET);
 301
 302        regmap_write(priv->map, JZ_REG_LCD_HSYNC,
 303                     0 << JZ_LCD_HSYNC_HPS_OFFSET |
 304                     hpe << JZ_LCD_HSYNC_HPE_OFFSET);
 305
 306        regmap_write(priv->map, JZ_REG_LCD_VAT,
 307                     ht << JZ_LCD_VAT_HT_OFFSET |
 308                     vt << JZ_LCD_VAT_VT_OFFSET);
 309
 310        regmap_write(priv->map, JZ_REG_LCD_DAH,
 311                     hds << JZ_LCD_DAH_HDS_OFFSET |
 312                     hde << JZ_LCD_DAH_HDE_OFFSET);
 313        regmap_write(priv->map, JZ_REG_LCD_DAV,
 314                     vds << JZ_LCD_DAV_VDS_OFFSET |
 315                     vde << JZ_LCD_DAV_VDE_OFFSET);
 316
 317        if (priv->panel_is_sharp) {
 318                regmap_write(priv->map, JZ_REG_LCD_PS, hde << 16 | (hde + 1));
 319                regmap_write(priv->map, JZ_REG_LCD_CLS, hde << 16 | (hde + 1));
 320                regmap_write(priv->map, JZ_REG_LCD_SPL, hpe << 16 | (hpe + 1));
 321                regmap_write(priv->map, JZ_REG_LCD_REV, mode->htotal << 16);
 322        }
 323
 324        regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
 325                           JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_MASK,
 326                           JZ_LCD_CTRL_OFUP | priv->soc_info->max_burst);
 327
 328        /*
 329         * IPU restart - specify how much time the LCDC will wait before
 330         * transferring a new frame from the IPU. The value is the one
 331         * suggested in the programming manual.
 332         */
 333        regmap_write(priv->map, JZ_REG_LCD_IPUR, JZ_LCD_IPUR_IPUREN |
 334                     (ht * vpe / 3) << JZ_LCD_IPUR_IPUR_LSB);
 335}
 336
 337static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc,
 338                                         struct drm_atomic_state *state)
 339{
 340        struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 341                                                                          crtc);
 342        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 343        struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL;
 344
 345        if (crtc_state->gamma_lut &&
 346            drm_color_lut_size(crtc_state->gamma_lut) != ARRAY_SIZE(priv->dma_hwdescs->palette)) {
 347                dev_dbg(priv->dev, "Invalid palette size\n");
 348                return -EINVAL;
 349        }
 350
 351        if (drm_atomic_crtc_needs_modeset(crtc_state) && priv->soc_info->has_osd) {
 352                f1_state = drm_atomic_get_plane_state(crtc_state->state,
 353                                                      &priv->f1);
 354                if (IS_ERR(f1_state))
 355                        return PTR_ERR(f1_state);
 356
 357                f0_state = drm_atomic_get_plane_state(crtc_state->state,
 358                                                      &priv->f0);
 359                if (IS_ERR(f0_state))
 360                        return PTR_ERR(f0_state);
 361
 362                if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && priv->ipu_plane) {
 363                        ipu_state = drm_atomic_get_plane_state(crtc_state->state,
 364                                                               priv->ipu_plane);
 365                        if (IS_ERR(ipu_state))
 366                                return PTR_ERR(ipu_state);
 367
 368                        /* IPU and F1 planes cannot be enabled at the same time. */
 369                        if (f1_state->fb && ipu_state->fb) {
 370                                dev_dbg(priv->dev, "Cannot enable both F1 and IPU\n");
 371                                return -EINVAL;
 372                        }
 373                }
 374
 375                /* If all the planes are disabled, we won't get a VBLANK IRQ */
 376                priv->no_vblank = !f1_state->fb && !f0_state->fb &&
 377                                  !(ipu_state && ipu_state->fb);
 378        }
 379
 380        return 0;
 381}
 382
 383static enum drm_mode_status
 384ingenic_drm_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
 385{
 386        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 387        long rate;
 388
 389        if (mode->hdisplay > priv->soc_info->max_width)
 390                return MODE_BAD_HVALUE;
 391        if (mode->vdisplay > priv->soc_info->max_height)
 392                return MODE_BAD_VVALUE;
 393
 394        rate = clk_round_rate(priv->pix_clk, mode->clock * 1000);
 395        if (rate < 0)
 396                return MODE_CLOCK_RANGE;
 397
 398        return MODE_OK;
 399}
 400
 401static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 402                                          struct drm_atomic_state *state)
 403{
 404        struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 405                                                                          crtc);
 406        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 407        u32 ctrl = 0;
 408
 409        if (priv->soc_info->has_osd &&
 410            drm_atomic_crtc_needs_modeset(crtc_state)) {
 411                /*
 412                 * If IPU plane is enabled, enable IPU as source for the F1
 413                 * plane; otherwise use regular DMA.
 414                 */
 415                if (priv->ipu_plane && priv->ipu_plane->state->fb)
 416                        ctrl |= JZ_LCD_OSDCTRL_IPU;
 417
 418                regmap_update_bits(priv->map, JZ_REG_LCD_OSDCTRL,
 419                                   JZ_LCD_OSDCTRL_IPU, ctrl);
 420        }
 421}
 422
 423static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 424                                          struct drm_atomic_state *state)
 425{
 426        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 427        struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 428                                                                          crtc);
 429        struct drm_pending_vblank_event *event = crtc_state->event;
 430
 431        if (drm_atomic_crtc_needs_modeset(crtc_state)) {
 432                ingenic_drm_crtc_update_timings(priv, &crtc_state->adjusted_mode);
 433                priv->update_clk_rate = true;
 434        }
 435
 436        if (priv->update_clk_rate) {
 437                mutex_lock(&priv->clk_mutex);
 438                clk_set_rate(priv->pix_clk,
 439                             crtc_state->adjusted_mode.crtc_clock * 1000);
 440                priv->update_clk_rate = false;
 441                mutex_unlock(&priv->clk_mutex);
 442        }
 443
 444        if (event) {
 445                crtc_state->event = NULL;
 446
 447                spin_lock_irq(&crtc->dev->event_lock);
 448                if (drm_crtc_vblank_get(crtc) == 0)
 449                        drm_crtc_arm_vblank_event(crtc, event);
 450                else
 451                        drm_crtc_send_vblank_event(crtc, event);
 452                spin_unlock_irq(&crtc->dev->event_lock);
 453        }
 454}
 455
 456static int ingenic_drm_plane_atomic_check(struct drm_plane *plane,
 457                                          struct drm_atomic_state *state)
 458{
 459        struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
 460                                                                                 plane);
 461        struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 462                                                                                 plane);
 463        struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
 464        struct ingenic_drm_private_state *priv_state;
 465        struct drm_crtc_state *crtc_state;
 466        struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
 467        int ret;
 468
 469        if (!crtc)
 470                return 0;
 471
 472        if (priv->soc_info->plane_f0_not_working && plane == &priv->f0)
 473                return -EINVAL;
 474
 475        crtc_state = drm_atomic_get_existing_crtc_state(state,
 476                                                        crtc);
 477        if (WARN_ON(!crtc_state))
 478                return -EINVAL;
 479
 480        priv_state = ingenic_drm_get_priv_state(priv, state);
 481        if (IS_ERR(priv_state))
 482                return PTR_ERR(priv_state);
 483
 484        ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 485                                                  DRM_PLANE_HELPER_NO_SCALING,
 486                                                  DRM_PLANE_HELPER_NO_SCALING,
 487                                                  priv->soc_info->has_osd,
 488                                                  true);
 489        if (ret)
 490                return ret;
 491
 492        /*
 493         * If OSD is not available, check that the width/height match.
 494         * Note that state->src_* are in 16.16 fixed-point format.
 495         */
 496        if (!priv->soc_info->has_osd &&
 497            (new_plane_state->src_x != 0 ||
 498             (new_plane_state->src_w >> 16) != new_plane_state->crtc_w ||
 499             (new_plane_state->src_h >> 16) != new_plane_state->crtc_h))
 500                return -EINVAL;
 501
 502        priv_state->use_palette = new_plane_state->fb &&
 503                new_plane_state->fb->format->format == DRM_FORMAT_C8;
 504
 505        /*
 506         * Require full modeset if enabling or disabling a plane, or changing
 507         * its position, size or depth.
 508         */
 509        if (priv->soc_info->has_osd &&
 510            (!old_plane_state->fb || !new_plane_state->fb ||
 511             old_plane_state->crtc_x != new_plane_state->crtc_x ||
 512             old_plane_state->crtc_y != new_plane_state->crtc_y ||
 513             old_plane_state->crtc_w != new_plane_state->crtc_w ||
 514             old_plane_state->crtc_h != new_plane_state->crtc_h ||
 515             old_plane_state->fb->format->format != new_plane_state->fb->format->format))
 516                crtc_state->mode_changed = true;
 517
 518        if (priv->soc_info->map_noncoherent)
 519                drm_atomic_helper_check_plane_damage(state, new_plane_state);
 520
 521        return 0;
 522}
 523
 524static void ingenic_drm_plane_enable(struct ingenic_drm *priv,
 525                                     struct drm_plane *plane)
 526{
 527        unsigned int en_bit;
 528
 529        if (priv->soc_info->has_osd) {
 530                if (plane != &priv->f0)
 531                        en_bit = JZ_LCD_OSDC_F1EN;
 532                else
 533                        en_bit = JZ_LCD_OSDC_F0EN;
 534
 535                regmap_set_bits(priv->map, JZ_REG_LCD_OSDC, en_bit);
 536        }
 537}
 538
 539void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane)
 540{
 541        struct ingenic_drm *priv = dev_get_drvdata(dev);
 542        unsigned int en_bit;
 543
 544        if (priv->soc_info->has_osd) {
 545                if (plane != &priv->f0)
 546                        en_bit = JZ_LCD_OSDC_F1EN;
 547                else
 548                        en_bit = JZ_LCD_OSDC_F0EN;
 549
 550                regmap_clear_bits(priv->map, JZ_REG_LCD_OSDC, en_bit);
 551        }
 552}
 553
 554static void ingenic_drm_plane_atomic_disable(struct drm_plane *plane,
 555                                             struct drm_atomic_state *state)
 556{
 557        struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
 558
 559        ingenic_drm_plane_disable(priv->dev, plane);
 560}
 561
 562void ingenic_drm_plane_config(struct device *dev,
 563                              struct drm_plane *plane, u32 fourcc)
 564{
 565        struct ingenic_drm *priv = dev_get_drvdata(dev);
 566        struct drm_plane_state *state = plane->state;
 567        unsigned int xy_reg, size_reg;
 568        unsigned int ctrl = 0;
 569
 570        ingenic_drm_plane_enable(priv, plane);
 571
 572        if (priv->soc_info->has_osd && plane != &priv->f0) {
 573                switch (fourcc) {
 574                case DRM_FORMAT_XRGB1555:
 575                        ctrl |= JZ_LCD_OSDCTRL_RGB555;
 576                        fallthrough;
 577                case DRM_FORMAT_RGB565:
 578                        ctrl |= JZ_LCD_OSDCTRL_BPP_15_16;
 579                        break;
 580                case DRM_FORMAT_RGB888:
 581                        ctrl |= JZ_LCD_OSDCTRL_BPP_24_COMP;
 582                        break;
 583                case DRM_FORMAT_XRGB8888:
 584                        ctrl |= JZ_LCD_OSDCTRL_BPP_18_24;
 585                        break;
 586                case DRM_FORMAT_XRGB2101010:
 587                        ctrl |= JZ_LCD_OSDCTRL_BPP_30;
 588                        break;
 589                }
 590
 591                regmap_update_bits(priv->map, JZ_REG_LCD_OSDCTRL,
 592                                   JZ_LCD_OSDCTRL_BPP_MASK, ctrl);
 593        } else {
 594                switch (fourcc) {
 595                case DRM_FORMAT_C8:
 596                        ctrl |= JZ_LCD_CTRL_BPP_8;
 597                        break;
 598                case DRM_FORMAT_XRGB1555:
 599                        ctrl |= JZ_LCD_CTRL_RGB555;
 600                        fallthrough;
 601                case DRM_FORMAT_RGB565:
 602                        ctrl |= JZ_LCD_CTRL_BPP_15_16;
 603                        break;
 604                case DRM_FORMAT_RGB888:
 605                        ctrl |= JZ_LCD_CTRL_BPP_24_COMP;
 606                        break;
 607                case DRM_FORMAT_XRGB8888:
 608                        ctrl |= JZ_LCD_CTRL_BPP_18_24;
 609                        break;
 610                case DRM_FORMAT_XRGB2101010:
 611                        ctrl |= JZ_LCD_CTRL_BPP_30;
 612                        break;
 613                }
 614
 615                regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
 616                                   JZ_LCD_CTRL_BPP_MASK, ctrl);
 617        }
 618
 619        if (priv->soc_info->has_osd) {
 620                if (plane != &priv->f0) {
 621                        xy_reg = JZ_REG_LCD_XYP1;
 622                        size_reg = JZ_REG_LCD_SIZE1;
 623                } else {
 624                        xy_reg = JZ_REG_LCD_XYP0;
 625                        size_reg = JZ_REG_LCD_SIZE0;
 626                }
 627
 628                regmap_write(priv->map, xy_reg,
 629                             state->crtc_x << JZ_LCD_XYP01_XPOS_LSB |
 630                             state->crtc_y << JZ_LCD_XYP01_YPOS_LSB);
 631                regmap_write(priv->map, size_reg,
 632                             state->crtc_w << JZ_LCD_SIZE01_WIDTH_LSB |
 633                             state->crtc_h << JZ_LCD_SIZE01_HEIGHT_LSB);
 634        }
 635}
 636
 637bool ingenic_drm_map_noncoherent(const struct device *dev)
 638{
 639        const struct ingenic_drm *priv = dev_get_drvdata(dev);
 640
 641        return priv->soc_info->map_noncoherent;
 642}
 643
 644static void ingenic_drm_update_palette(struct ingenic_drm *priv,
 645                                       const struct drm_color_lut *lut)
 646{
 647        unsigned int i;
 648
 649        for (i = 0; i < ARRAY_SIZE(priv->dma_hwdescs->palette); i++) {
 650                u16 color = drm_color_lut_extract(lut[i].red, 5) << 11
 651                        | drm_color_lut_extract(lut[i].green, 6) << 5
 652                        | drm_color_lut_extract(lut[i].blue, 5);
 653
 654                priv->dma_hwdescs->palette[i] = color;
 655        }
 656}
 657
 658static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
 659                                            struct drm_atomic_state *state)
 660{
 661        struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
 662        struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, plane);
 663        struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, plane);
 664        unsigned int width, height, cpp, next_id, plane_id;
 665        struct ingenic_drm_private_state *priv_state;
 666        struct drm_crtc_state *crtc_state;
 667        struct ingenic_dma_hwdesc *hwdesc;
 668        dma_addr_t addr;
 669        u32 fourcc;
 670
 671        if (newstate && newstate->fb) {
 672                if (priv->soc_info->map_noncoherent)
 673                        drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, newstate);
 674
 675                crtc_state = newstate->crtc->state;
 676                plane_id = !!(priv->soc_info->has_osd && plane != &priv->f0);
 677
 678                addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
 679                width = newstate->src_w >> 16;
 680                height = newstate->src_h >> 16;
 681                cpp = newstate->fb->format->cpp[0];
 682
 683                priv_state = ingenic_drm_get_new_priv_state(priv, state);
 684                next_id = (priv_state && priv_state->use_palette) ? HWDESC_PALETTE : plane_id;
 685
 686                hwdesc = &priv->dma_hwdescs->hwdesc[plane_id];
 687                hwdesc->addr = addr;
 688                hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
 689                hwdesc->next = dma_hwdesc_addr(priv, next_id);
 690
 691                if (priv->soc_info->use_extended_hwdesc) {
 692                        hwdesc->cmd |= JZ_LCD_CMD_FRM_ENABLE;
 693
 694                        /* Extended 8-byte descriptor */
 695                        hwdesc->cpos = 0;
 696                        hwdesc->offsize = 0;
 697                        hwdesc->pagewidth = 0;
 698
 699                        switch (newstate->fb->format->format) {
 700                        case DRM_FORMAT_XRGB1555:
 701                                hwdesc->cpos |= JZ_LCD_CPOS_RGB555;
 702                                fallthrough;
 703                        case DRM_FORMAT_RGB565:
 704                                hwdesc->cpos |= JZ_LCD_CPOS_BPP_15_16;
 705                                break;
 706                        case DRM_FORMAT_XRGB8888:
 707                                hwdesc->cpos |= JZ_LCD_CPOS_BPP_18_24;
 708                                break;
 709                        }
 710                        hwdesc->cpos |= (JZ_LCD_CPOS_COEFFICIENT_1 <<
 711                                         JZ_LCD_CPOS_COEFFICIENT_OFFSET);
 712                        hwdesc->dessize =
 713                                (0xff << JZ_LCD_DESSIZE_ALPHA_OFFSET) |
 714                                FIELD_PREP(JZ_LCD_DESSIZE_HEIGHT_MASK, height - 1) |
 715                                FIELD_PREP(JZ_LCD_DESSIZE_WIDTH_MASK, width - 1);
 716                }
 717
 718                if (drm_atomic_crtc_needs_modeset(crtc_state)) {
 719                        fourcc = newstate->fb->format->format;
 720
 721                        ingenic_drm_plane_config(priv->dev, plane, fourcc);
 722
 723                        crtc_state->color_mgmt_changed = fourcc == DRM_FORMAT_C8;
 724                }
 725
 726                if (crtc_state->color_mgmt_changed)
 727                        ingenic_drm_update_palette(priv, crtc_state->gamma_lut->data);
 728        }
 729}
 730
 731static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,
 732                                                struct drm_crtc_state *crtc_state,
 733                                                struct drm_connector_state *conn_state)
 734{
 735        struct ingenic_drm *priv = drm_device_get_priv(encoder->dev);
 736        struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 737        struct ingenic_drm_bridge *bridge = to_ingenic_drm_bridge(encoder);
 738        unsigned int cfg, rgbcfg = 0;
 739
 740        priv->panel_is_sharp = bridge->bus_cfg.flags & DRM_BUS_FLAG_SHARP_SIGNALS;
 741
 742        if (priv->panel_is_sharp) {
 743                cfg = JZ_LCD_CFG_MODE_SPECIAL_TFT_1 | JZ_LCD_CFG_REV_POLARITY;
 744        } else {
 745                cfg = JZ_LCD_CFG_PS_DISABLE | JZ_LCD_CFG_CLS_DISABLE
 746                    | JZ_LCD_CFG_SPL_DISABLE | JZ_LCD_CFG_REV_DISABLE;
 747        }
 748
 749        if (priv->soc_info->use_extended_hwdesc)
 750                cfg |= JZ_LCD_CFG_DESCRIPTOR_8;
 751
 752        if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 753                cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
 754        if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 755                cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
 756        if (bridge->bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
 757                cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
 758        if (bridge->bus_cfg.flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
 759                cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
 760
 761        if (!priv->panel_is_sharp) {
 762                if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV) {
 763                        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 764                                cfg |= JZ_LCD_CFG_MODE_TV_OUT_I;
 765                        else
 766                                cfg |= JZ_LCD_CFG_MODE_TV_OUT_P;
 767                } else {
 768                        switch (bridge->bus_cfg.format) {
 769                        case MEDIA_BUS_FMT_RGB565_1X16:
 770                                cfg |= JZ_LCD_CFG_MODE_GENERIC_16BIT;
 771                                break;
 772                        case MEDIA_BUS_FMT_RGB666_1X18:
 773                                cfg |= JZ_LCD_CFG_MODE_GENERIC_18BIT;
 774                                break;
 775                        case MEDIA_BUS_FMT_RGB888_1X24:
 776                                cfg |= JZ_LCD_CFG_MODE_GENERIC_24BIT;
 777                                break;
 778                        case MEDIA_BUS_FMT_RGB888_3X8_DELTA:
 779                                rgbcfg = JZ_LCD_RGBC_EVEN_GBR | JZ_LCD_RGBC_ODD_RGB;
 780                                fallthrough;
 781                        case MEDIA_BUS_FMT_RGB888_3X8:
 782                                cfg |= JZ_LCD_CFG_MODE_8BIT_SERIAL;
 783                                break;
 784                        default:
 785                                break;
 786                        }
 787                }
 788        }
 789
 790        regmap_write(priv->map, JZ_REG_LCD_CFG, cfg);
 791        regmap_write(priv->map, JZ_REG_LCD_RGBC, rgbcfg);
 792}
 793
 794static int ingenic_drm_bridge_attach(struct drm_bridge *bridge,
 795                                     enum drm_bridge_attach_flags flags)
 796{
 797        struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge->encoder);
 798
 799        return drm_bridge_attach(bridge->encoder, ib->next_bridge,
 800                                 &ib->bridge, flags);
 801}
 802
 803static int ingenic_drm_bridge_atomic_check(struct drm_bridge *bridge,
 804                                           struct drm_bridge_state *bridge_state,
 805                                           struct drm_crtc_state *crtc_state,
 806                                           struct drm_connector_state *conn_state)
 807{
 808        struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 809        struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge->encoder);
 810
 811        ib->bus_cfg = bridge_state->output_bus_cfg;
 812
 813        if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV)
 814                return 0;
 815
 816        switch (bridge_state->output_bus_cfg.format) {
 817        case MEDIA_BUS_FMT_RGB888_3X8:
 818        case MEDIA_BUS_FMT_RGB888_3X8_DELTA:
 819                /*
 820                 * The LCD controller expects timing values in dot-clock ticks,
 821                 * which is 3x the timing values in pixels when using a 3x8-bit
 822                 * display; but it will count the display area size in pixels
 823                 * either way. Go figure.
 824                 */
 825                mode->crtc_clock = mode->clock * 3;
 826                mode->crtc_hsync_start = mode->hsync_start * 3 - mode->hdisplay * 2;
 827                mode->crtc_hsync_end = mode->hsync_end * 3 - mode->hdisplay * 2;
 828                mode->crtc_hdisplay = mode->hdisplay;
 829                mode->crtc_htotal = mode->htotal * 3 - mode->hdisplay * 2;
 830                return 0;
 831        case MEDIA_BUS_FMT_RGB565_1X16:
 832        case MEDIA_BUS_FMT_RGB666_1X18:
 833        case MEDIA_BUS_FMT_RGB888_1X24:
 834                return 0;
 835        default:
 836                return -EINVAL;
 837        }
 838}
 839
 840static u32 *
 841ingenic_drm_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 842                                             struct drm_bridge_state *bridge_state,
 843                                             struct drm_crtc_state *crtc_state,
 844                                             struct drm_connector_state *conn_state,
 845                                             u32 output_fmt,
 846                                             unsigned int *num_input_fmts)
 847{
 848        switch (output_fmt) {
 849        case MEDIA_BUS_FMT_RGB888_1X24:
 850        case MEDIA_BUS_FMT_RGB666_1X18:
 851        case MEDIA_BUS_FMT_RGB565_1X16:
 852        case MEDIA_BUS_FMT_RGB888_3X8:
 853        case MEDIA_BUS_FMT_RGB888_3X8_DELTA:
 854                break;
 855        default:
 856                *num_input_fmts = 0;
 857                return NULL;
 858        }
 859
 860        return drm_atomic_helper_bridge_propagate_bus_fmt(bridge, bridge_state,
 861                                                          crtc_state, conn_state,
 862                                                          output_fmt,
 863                                                          num_input_fmts);
 864}
 865
 866static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 867{
 868        struct ingenic_drm *priv = drm_device_get_priv(arg);
 869        unsigned int state;
 870
 871        regmap_read(priv->map, JZ_REG_LCD_STATE, &state);
 872
 873        regmap_update_bits(priv->map, JZ_REG_LCD_STATE,
 874                           JZ_LCD_STATE_EOF_IRQ, 0);
 875
 876        if (state & JZ_LCD_STATE_EOF_IRQ)
 877                drm_crtc_handle_vblank(&priv->crtc);
 878
 879        return IRQ_HANDLED;
 880}
 881
 882static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
 883{
 884        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 885
 886        if (priv->no_vblank)
 887                return -EINVAL;
 888
 889        regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
 890                           JZ_LCD_CTRL_EOF_IRQ, JZ_LCD_CTRL_EOF_IRQ);
 891
 892        return 0;
 893}
 894
 895static void ingenic_drm_disable_vblank(struct drm_crtc *crtc)
 896{
 897        struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
 898
 899        regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, JZ_LCD_CTRL_EOF_IRQ, 0);
 900}
 901
 902static struct drm_framebuffer *
 903ingenic_drm_gem_fb_create(struct drm_device *drm, struct drm_file *file,
 904                          const struct drm_mode_fb_cmd2 *mode_cmd)
 905{
 906        struct ingenic_drm *priv = drm_device_get_priv(drm);
 907
 908        if (priv->soc_info->map_noncoherent)
 909                return drm_gem_fb_create_with_dirty(drm, file, mode_cmd);
 910
 911        return drm_gem_fb_create(drm, file, mode_cmd);
 912}
 913
 914static struct drm_gem_object *
 915ingenic_drm_gem_create_object(struct drm_device *drm, size_t size)
 916{
 917        struct ingenic_drm *priv = drm_device_get_priv(drm);
 918        struct drm_gem_cma_object *obj;
 919
 920        obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 921        if (!obj)
 922                return ERR_PTR(-ENOMEM);
 923
 924        obj->map_noncoherent = priv->soc_info->map_noncoherent;
 925
 926        return &obj->base;
 927}
 928
 929static struct drm_private_state *
 930ingenic_drm_duplicate_state(struct drm_private_obj *obj)
 931{
 932        struct ingenic_drm_private_state *state = to_ingenic_drm_priv_state(obj->state);
 933
 934        state = kmemdup(state, sizeof(*state), GFP_KERNEL);
 935        if (!state)
 936                return NULL;
 937
 938        __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
 939
 940        return &state->base;
 941}
 942
 943static void ingenic_drm_destroy_state(struct drm_private_obj *obj,
 944                                      struct drm_private_state *state)
 945{
 946        struct ingenic_drm_private_state *priv_state = to_ingenic_drm_priv_state(state);
 947
 948        kfree(priv_state);
 949}
 950
 951DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops);
 952
 953static const struct drm_driver ingenic_drm_driver_data = {
 954        .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 955        .name                   = "ingenic-drm",
 956        .desc                   = "DRM module for Ingenic SoCs",
 957        .date                   = "20200716",
 958        .major                  = 1,
 959        .minor                  = 1,
 960        .patchlevel             = 0,
 961
 962        .fops                   = &ingenic_drm_fops,
 963        .gem_create_object      = ingenic_drm_gem_create_object,
 964        DRM_GEM_CMA_DRIVER_OPS,
 965};
 966
 967static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = {
 968        .update_plane           = drm_atomic_helper_update_plane,
 969        .disable_plane          = drm_atomic_helper_disable_plane,
 970        .reset                  = drm_atomic_helper_plane_reset,
 971        .destroy                = drm_plane_cleanup,
 972
 973        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 974        .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
 975};
 976
 977static const struct drm_crtc_funcs ingenic_drm_crtc_funcs = {
 978        .set_config             = drm_atomic_helper_set_config,
 979        .page_flip              = drm_atomic_helper_page_flip,
 980        .reset                  = drm_atomic_helper_crtc_reset,
 981        .destroy                = drm_crtc_cleanup,
 982
 983        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 984        .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
 985
 986        .enable_vblank          = ingenic_drm_enable_vblank,
 987        .disable_vblank         = ingenic_drm_disable_vblank,
 988};
 989
 990static const struct drm_plane_helper_funcs ingenic_drm_plane_helper_funcs = {
 991        .atomic_update          = ingenic_drm_plane_atomic_update,
 992        .atomic_check           = ingenic_drm_plane_atomic_check,
 993        .atomic_disable         = ingenic_drm_plane_atomic_disable,
 994};
 995
 996static const struct drm_crtc_helper_funcs ingenic_drm_crtc_helper_funcs = {
 997        .atomic_enable          = ingenic_drm_crtc_atomic_enable,
 998        .atomic_disable         = ingenic_drm_crtc_atomic_disable,
 999        .atomic_begin           = ingenic_drm_crtc_atomic_begin,
1000        .atomic_flush           = ingenic_drm_crtc_atomic_flush,
1001        .atomic_check           = ingenic_drm_crtc_atomic_check,
1002        .mode_valid             = ingenic_drm_crtc_mode_valid,
1003};
1004
1005static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = {
1006        .atomic_mode_set        = ingenic_drm_encoder_atomic_mode_set,
1007};
1008
1009static const struct drm_bridge_funcs ingenic_drm_bridge_funcs = {
1010        .attach                 = ingenic_drm_bridge_attach,
1011        .atomic_enable          = ingenic_drm_bridge_atomic_enable,
1012        .atomic_disable         = ingenic_drm_bridge_atomic_disable,
1013        .atomic_check           = ingenic_drm_bridge_atomic_check,
1014        .atomic_reset           = drm_atomic_helper_bridge_reset,
1015        .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
1016        .atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
1017        .atomic_get_input_bus_fmts = ingenic_drm_bridge_atomic_get_input_bus_fmts,
1018};
1019
1020static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = {
1021        .fb_create              = ingenic_drm_gem_fb_create,
1022        .output_poll_changed    = drm_fb_helper_output_poll_changed,
1023        .atomic_check           = drm_atomic_helper_check,
1024        .atomic_commit          = drm_atomic_helper_commit,
1025};
1026
1027static struct drm_mode_config_helper_funcs ingenic_drm_mode_config_helpers = {
1028        .atomic_commit_tail = drm_atomic_helper_commit_tail,
1029};
1030
1031static const struct drm_private_state_funcs ingenic_drm_private_state_funcs = {
1032        .atomic_duplicate_state = ingenic_drm_duplicate_state,
1033        .atomic_destroy_state = ingenic_drm_destroy_state,
1034};
1035
1036static void ingenic_drm_unbind_all(void *d)
1037{
1038        struct ingenic_drm *priv = d;
1039
1040        component_unbind_all(priv->dev, &priv->drm);
1041}
1042
1043static void __maybe_unused ingenic_drm_release_rmem(void *d)
1044{
1045        of_reserved_mem_device_release(d);
1046}
1047
1048static void ingenic_drm_configure_hwdesc(struct ingenic_drm *priv,
1049                                         unsigned int hwdesc,
1050                                         unsigned int next_hwdesc, u32 id)
1051{
1052        struct ingenic_dma_hwdesc *desc = &priv->dma_hwdescs->hwdesc[hwdesc];
1053
1054        desc->next = dma_hwdesc_addr(priv, next_hwdesc);
1055        desc->id = id;
1056}
1057
1058static void ingenic_drm_configure_hwdesc_palette(struct ingenic_drm *priv)
1059{
1060        struct ingenic_dma_hwdesc *desc;
1061
1062        ingenic_drm_configure_hwdesc(priv, HWDESC_PALETTE, 0, 0xc0);
1063
1064        desc = &priv->dma_hwdescs->hwdesc[HWDESC_PALETTE];
1065        desc->addr = priv->dma_hwdescs_phys
1066                + offsetof(struct ingenic_dma_hwdescs, palette);
1067        desc->cmd = JZ_LCD_CMD_ENABLE_PAL
1068                | (sizeof(priv->dma_hwdescs->palette) / 4);
1069}
1070
1071static void ingenic_drm_configure_hwdesc_plane(struct ingenic_drm *priv,
1072                                               unsigned int plane)
1073{
1074        ingenic_drm_configure_hwdesc(priv, plane, plane, 0xf0 | plane);
1075}
1076
1077static void ingenic_drm_atomic_private_obj_fini(struct drm_device *drm, void *private_obj)
1078{
1079        drm_atomic_private_obj_fini(private_obj);
1080}
1081
1082static int ingenic_drm_bind(struct device *dev, bool has_components)
1083{
1084        struct platform_device *pdev = to_platform_device(dev);
1085        struct ingenic_drm_private_state *private_state;
1086        const struct jz_soc_info *soc_info;
1087        struct ingenic_drm *priv;
1088        struct clk *parent_clk;
1089        struct drm_plane *primary;
1090        struct drm_bridge *bridge;
1091        struct drm_panel *panel;
1092        struct drm_connector *connector;
1093        struct drm_encoder *encoder;
1094        struct ingenic_drm_bridge *ib;
1095        struct drm_device *drm;
1096        void __iomem *base;
1097        struct resource *res;
1098        struct regmap_config regmap_config;
1099        long parent_rate;
1100        unsigned int i, clone_mask = 0;
1101        int ret, irq;
1102        u32 osdc = 0;
1103
1104        soc_info = of_device_get_match_data(dev);
1105        if (!soc_info) {
1106                dev_err(dev, "Missing platform data\n");
1107                return -EINVAL;
1108        }
1109
1110        if (IS_ENABLED(CONFIG_OF_RESERVED_MEM)) {
1111                ret = of_reserved_mem_device_init(dev);
1112
1113                if (ret && ret != -ENODEV)
1114                        dev_warn(dev, "Failed to get reserved memory: %d\n", ret);
1115
1116                if (!ret) {
1117                        ret = devm_add_action_or_reset(dev, ingenic_drm_release_rmem, dev);
1118                        if (ret)
1119                                return ret;
1120                }
1121        }
1122
1123        priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data,
1124                                  struct ingenic_drm, drm);
1125        if (IS_ERR(priv))
1126                return PTR_ERR(priv);
1127
1128        priv->soc_info = soc_info;
1129        priv->dev = dev;
1130        drm = &priv->drm;
1131
1132        platform_set_drvdata(pdev, priv);
1133
1134        ret = drmm_mode_config_init(drm);
1135        if (ret)
1136                return ret;
1137
1138        drm->mode_config.min_width = 0;
1139        drm->mode_config.min_height = 0;
1140        drm->mode_config.max_width = soc_info->max_width;
1141        drm->mode_config.max_height = 4095;
1142        drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
1143        drm->mode_config.helper_private = &ingenic_drm_mode_config_helpers;
1144
1145        base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1146        if (IS_ERR(base)) {
1147                dev_err(dev, "Failed to get memory resource\n");
1148                return PTR_ERR(base);
1149        }
1150
1151        regmap_config = ingenic_drm_regmap_config;
1152        regmap_config.max_register = res->end - res->start;
1153        priv->map = devm_regmap_init_mmio(dev, base,
1154                                          &regmap_config);
1155        if (IS_ERR(priv->map)) {
1156                dev_err(dev, "Failed to create regmap\n");
1157                return PTR_ERR(priv->map);
1158        }
1159
1160        irq = platform_get_irq(pdev, 0);
1161        if (irq < 0)
1162                return irq;
1163
1164        if (soc_info->needs_dev_clk) {
1165                priv->lcd_clk = devm_clk_get(dev, "lcd");
1166                if (IS_ERR(priv->lcd_clk)) {
1167                        dev_err(dev, "Failed to get lcd clock\n");
1168                        return PTR_ERR(priv->lcd_clk);
1169                }
1170        }
1171
1172        priv->pix_clk = devm_clk_get(dev, "lcd_pclk");
1173        if (IS_ERR(priv->pix_clk)) {
1174                dev_err(dev, "Failed to get pixel clock\n");
1175                return PTR_ERR(priv->pix_clk);
1176        }
1177
1178        priv->dma_hwdescs = dmam_alloc_coherent(dev,
1179                                                sizeof(*priv->dma_hwdescs),
1180                                                &priv->dma_hwdescs_phys,
1181                                                GFP_KERNEL);
1182        if (!priv->dma_hwdescs)
1183                return -ENOMEM;
1184
1185        /* Configure DMA hwdesc for foreground0 plane */
1186        ingenic_drm_configure_hwdesc_plane(priv, 0);
1187
1188        /* Configure DMA hwdesc for foreground1 plane */
1189        ingenic_drm_configure_hwdesc_plane(priv, 1);
1190
1191        /* Configure DMA hwdesc for palette */
1192        ingenic_drm_configure_hwdesc_palette(priv);
1193
1194        primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0;
1195
1196        drm_plane_helper_add(primary, &ingenic_drm_plane_helper_funcs);
1197
1198        ret = drm_universal_plane_init(drm, primary, 1,
1199                                       &ingenic_drm_primary_plane_funcs,
1200                                       priv->soc_info->formats_f1,
1201                                       priv->soc_info->num_formats_f1,
1202                                       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1203        if (ret) {
1204                dev_err(dev, "Failed to register plane: %i\n", ret);
1205                return ret;
1206        }
1207
1208        if (soc_info->map_noncoherent)
1209                drm_plane_enable_fb_damage_clips(&priv->f1);
1210
1211        drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs);
1212
1213        ret = drm_crtc_init_with_planes(drm, &priv->crtc, primary,
1214                                        NULL, &ingenic_drm_crtc_funcs, NULL);
1215        if (ret) {
1216                dev_err(dev, "Failed to init CRTC: %i\n", ret);
1217                return ret;
1218        }
1219
1220        drm_crtc_enable_color_mgmt(&priv->crtc, 0, false,
1221                                   ARRAY_SIZE(priv->dma_hwdescs->palette));
1222
1223        if (soc_info->has_osd) {
1224                drm_plane_helper_add(&priv->f0,
1225                                     &ingenic_drm_plane_helper_funcs);
1226
1227                ret = drm_universal_plane_init(drm, &priv->f0, 1,
1228                                               &ingenic_drm_primary_plane_funcs,
1229                                               priv->soc_info->formats_f0,
1230                                               priv->soc_info->num_formats_f0,
1231                                               NULL, DRM_PLANE_TYPE_OVERLAY,
1232                                               NULL);
1233                if (ret) {
1234                        dev_err(dev, "Failed to register overlay plane: %i\n",
1235                                ret);
1236                        return ret;
1237                }
1238
1239                if (soc_info->map_noncoherent)
1240                        drm_plane_enable_fb_damage_clips(&priv->f0);
1241
1242                if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && has_components) {
1243                        ret = component_bind_all(dev, drm);
1244                        if (ret) {
1245                                if (ret != -EPROBE_DEFER)
1246                                        dev_err(dev, "Failed to bind components: %i\n", ret);
1247                                return ret;
1248                        }
1249
1250                        ret = devm_add_action_or_reset(dev, ingenic_drm_unbind_all, priv);
1251                        if (ret)
1252                                return ret;
1253
1254                        priv->ipu_plane = drm_plane_from_index(drm, 2);
1255                        if (!priv->ipu_plane) {
1256                                dev_err(dev, "Failed to retrieve IPU plane\n");
1257                                return -EINVAL;
1258                        }
1259                }
1260        }
1261
1262        for (i = 0; ; i++) {
1263                ret = drm_of_find_panel_or_bridge(dev->of_node, 0, i, &panel, &bridge);
1264                if (ret) {
1265                        if (ret == -ENODEV)
1266                                break; /* we're done */
1267                        if (ret != -EPROBE_DEFER)
1268                                dev_err(dev, "Failed to get bridge handle\n");
1269                        return ret;
1270                }
1271
1272                if (panel)
1273                        bridge = devm_drm_panel_bridge_add_typed(dev, panel,
1274                                                                 DRM_MODE_CONNECTOR_DPI);
1275
1276                ib = drmm_encoder_alloc(drm, struct ingenic_drm_bridge, encoder,
1277                                        NULL, DRM_MODE_ENCODER_DPI, NULL);
1278                if (IS_ERR(ib)) {
1279                        ret = PTR_ERR(ib);
1280                        dev_err(dev, "Failed to init encoder: %d\n", ret);
1281                        return ret;
1282                }
1283
1284                encoder = &ib->encoder;
1285                encoder->possible_crtcs = drm_crtc_mask(&priv->crtc);
1286
1287                drm_encoder_helper_add(encoder, &ingenic_drm_encoder_helper_funcs);
1288
1289                ib->bridge.funcs = &ingenic_drm_bridge_funcs;
1290                ib->next_bridge = bridge;
1291
1292                ret = drm_bridge_attach(encoder, &ib->bridge, NULL,
1293                                        DRM_BRIDGE_ATTACH_NO_CONNECTOR);
1294                if (ret) {
1295                        dev_err(dev, "Unable to attach bridge\n");
1296                        return ret;
1297                }
1298
1299                connector = drm_bridge_connector_init(drm, encoder);
1300                if (IS_ERR(connector)) {
1301                        dev_err(dev, "Unable to init connector\n");
1302                        return PTR_ERR(connector);
1303                }
1304
1305                drm_connector_attach_encoder(connector, encoder);
1306        }
1307
1308        drm_for_each_encoder(encoder, drm) {
1309                clone_mask |= BIT(drm_encoder_index(encoder));
1310        }
1311
1312        drm_for_each_encoder(encoder, drm) {
1313                encoder->possible_clones = clone_mask;
1314        }
1315
1316        ret = devm_request_irq(dev, irq, ingenic_drm_irq_handler, 0, drm->driver->name, drm);
1317        if (ret) {
1318                dev_err(dev, "Unable to install IRQ handler\n");
1319                return ret;
1320        }
1321
1322        ret = drm_vblank_init(drm, 1);
1323        if (ret) {
1324                dev_err(dev, "Failed calling drm_vblank_init()\n");
1325                return ret;
1326        }
1327
1328        drm_mode_config_reset(drm);
1329
1330        ret = clk_prepare_enable(priv->pix_clk);
1331        if (ret) {
1332                dev_err(dev, "Unable to start pixel clock\n");
1333                return ret;
1334        }
1335
1336        if (priv->lcd_clk) {
1337                parent_clk = clk_get_parent(priv->lcd_clk);
1338                parent_rate = clk_get_rate(parent_clk);
1339
1340                /* LCD Device clock must be 3x the pixel clock for STN panels,
1341                 * or 1.5x the pixel clock for TFT panels. To avoid having to
1342                 * check for the LCD device clock everytime we do a mode change,
1343                 * we set the LCD device clock to the highest rate possible.
1344                 */
1345                ret = clk_set_rate(priv->lcd_clk, parent_rate);
1346                if (ret) {
1347                        dev_err(dev, "Unable to set LCD clock rate\n");
1348                        goto err_pixclk_disable;
1349                }
1350
1351                ret = clk_prepare_enable(priv->lcd_clk);
1352                if (ret) {
1353                        dev_err(dev, "Unable to start lcd clock\n");
1354                        goto err_pixclk_disable;
1355                }
1356        }
1357
1358        /* Enable OSD if available */
1359        if (soc_info->has_osd)
1360                osdc |= JZ_LCD_OSDC_OSDEN;
1361        if (soc_info->has_alpha)
1362                osdc |= JZ_LCD_OSDC_ALPHAEN;
1363        regmap_write(priv->map, JZ_REG_LCD_OSDC, osdc);
1364
1365        mutex_init(&priv->clk_mutex);
1366        priv->clock_nb.notifier_call = ingenic_drm_update_pixclk;
1367
1368        parent_clk = clk_get_parent(priv->pix_clk);
1369        ret = clk_notifier_register(parent_clk, &priv->clock_nb);
1370        if (ret) {
1371                dev_err(dev, "Unable to register clock notifier\n");
1372                goto err_devclk_disable;
1373        }
1374
1375        private_state = kzalloc(sizeof(*private_state), GFP_KERNEL);
1376        if (!private_state) {
1377                ret = -ENOMEM;
1378                goto err_clk_notifier_unregister;
1379        }
1380
1381        drm_atomic_private_obj_init(drm, &priv->private_obj, &private_state->base,
1382                                    &ingenic_drm_private_state_funcs);
1383
1384        ret = drmm_add_action_or_reset(drm, ingenic_drm_atomic_private_obj_fini,
1385                                       &priv->private_obj);
1386        if (ret)
1387                goto err_private_state_free;
1388
1389        ret = drm_dev_register(drm, 0);
1390        if (ret) {
1391                dev_err(dev, "Failed to register DRM driver\n");
1392                goto err_clk_notifier_unregister;
1393        }
1394
1395        drm_fbdev_generic_setup(drm, 32);
1396
1397        return 0;
1398
1399err_private_state_free:
1400        kfree(private_state);
1401err_clk_notifier_unregister:
1402        clk_notifier_unregister(parent_clk, &priv->clock_nb);
1403err_devclk_disable:
1404        if (priv->lcd_clk)
1405                clk_disable_unprepare(priv->lcd_clk);
1406err_pixclk_disable:
1407        clk_disable_unprepare(priv->pix_clk);
1408        return ret;
1409}
1410
1411static int ingenic_drm_bind_with_components(struct device *dev)
1412{
1413        return ingenic_drm_bind(dev, true);
1414}
1415
1416static void ingenic_drm_unbind(struct device *dev)
1417{
1418        struct ingenic_drm *priv = dev_get_drvdata(dev);
1419        struct clk *parent_clk = clk_get_parent(priv->pix_clk);
1420
1421        clk_notifier_unregister(parent_clk, &priv->clock_nb);
1422        if (priv->lcd_clk)
1423                clk_disable_unprepare(priv->lcd_clk);
1424        clk_disable_unprepare(priv->pix_clk);
1425
1426        drm_dev_unregister(&priv->drm);
1427        drm_atomic_helper_shutdown(&priv->drm);
1428}
1429
1430static const struct component_master_ops ingenic_master_ops = {
1431        .bind = ingenic_drm_bind_with_components,
1432        .unbind = ingenic_drm_unbind,
1433};
1434
1435static int ingenic_drm_probe(struct platform_device *pdev)
1436{
1437        struct device *dev = &pdev->dev;
1438        struct component_match *match = NULL;
1439        struct device_node *np;
1440
1441        if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU))
1442                return ingenic_drm_bind(dev, false);
1443
1444        /* IPU is at port address 8 */
1445        np = of_graph_get_remote_node(dev->of_node, 8, 0);
1446        if (!np)
1447                return ingenic_drm_bind(dev, false);
1448
1449        drm_of_component_match_add(dev, &match, component_compare_of, np);
1450        of_node_put(np);
1451
1452        return component_master_add_with_match(dev, &ingenic_master_ops, match);
1453}
1454
1455static int ingenic_drm_remove(struct platform_device *pdev)
1456{
1457        struct device *dev = &pdev->dev;
1458
1459        if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU))
1460                ingenic_drm_unbind(dev);
1461        else
1462                component_master_del(dev, &ingenic_master_ops);
1463
1464        return 0;
1465}
1466
1467static int __maybe_unused ingenic_drm_suspend(struct device *dev)
1468{
1469        struct ingenic_drm *priv = dev_get_drvdata(dev);
1470
1471        return drm_mode_config_helper_suspend(&priv->drm);
1472}
1473
1474static int __maybe_unused ingenic_drm_resume(struct device *dev)
1475{
1476        struct ingenic_drm *priv = dev_get_drvdata(dev);
1477
1478        return drm_mode_config_helper_resume(&priv->drm);
1479}
1480
1481static SIMPLE_DEV_PM_OPS(ingenic_drm_pm_ops, ingenic_drm_suspend, ingenic_drm_resume);
1482
1483static const u32 jz4740_formats[] = {
1484        DRM_FORMAT_XRGB1555,
1485        DRM_FORMAT_RGB565,
1486        DRM_FORMAT_XRGB8888,
1487};
1488
1489static const u32 jz4725b_formats_f1[] = {
1490        DRM_FORMAT_XRGB1555,
1491        DRM_FORMAT_RGB565,
1492        DRM_FORMAT_XRGB8888,
1493};
1494
1495static const u32 jz4725b_formats_f0[] = {
1496        DRM_FORMAT_C8,
1497        DRM_FORMAT_XRGB1555,
1498        DRM_FORMAT_RGB565,
1499        DRM_FORMAT_XRGB8888,
1500};
1501
1502static const u32 jz4770_formats_f1[] = {
1503        DRM_FORMAT_XRGB1555,
1504        DRM_FORMAT_RGB565,
1505        DRM_FORMAT_RGB888,
1506        DRM_FORMAT_XRGB8888,
1507        DRM_FORMAT_XRGB2101010,
1508};
1509
1510static const u32 jz4770_formats_f0[] = {
1511        DRM_FORMAT_C8,
1512        DRM_FORMAT_XRGB1555,
1513        DRM_FORMAT_RGB565,
1514        DRM_FORMAT_RGB888,
1515        DRM_FORMAT_XRGB8888,
1516        DRM_FORMAT_XRGB2101010,
1517};
1518
1519static const struct jz_soc_info jz4740_soc_info = {
1520        .needs_dev_clk = true,
1521        .has_osd = false,
1522        .map_noncoherent = false,
1523        .max_width = 800,
1524        .max_height = 600,
1525        .max_burst = JZ_LCD_CTRL_BURST_16,
1526        .formats_f1 = jz4740_formats,
1527        .num_formats_f1 = ARRAY_SIZE(jz4740_formats),
1528        /* JZ4740 has only one plane */
1529};
1530
1531static const struct jz_soc_info jz4725b_soc_info = {
1532        .needs_dev_clk = false,
1533        .has_osd = true,
1534        .map_noncoherent = false,
1535        .max_width = 800,
1536        .max_height = 600,
1537        .max_burst = JZ_LCD_CTRL_BURST_16,
1538        .formats_f1 = jz4725b_formats_f1,
1539        .num_formats_f1 = ARRAY_SIZE(jz4725b_formats_f1),
1540        .formats_f0 = jz4725b_formats_f0,
1541        .num_formats_f0 = ARRAY_SIZE(jz4725b_formats_f0),
1542};
1543
1544static const struct jz_soc_info jz4770_soc_info = {
1545        .needs_dev_clk = false,
1546        .has_osd = true,
1547        .map_noncoherent = true,
1548        .max_width = 1280,
1549        .max_height = 720,
1550        .max_burst = JZ_LCD_CTRL_BURST_64,
1551        .formats_f1 = jz4770_formats_f1,
1552        .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1),
1553        .formats_f0 = jz4770_formats_f0,
1554        .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0),
1555};
1556
1557static const struct jz_soc_info jz4780_soc_info = {
1558        .needs_dev_clk = true,
1559        .has_osd = true,
1560        .has_alpha = true,
1561        .use_extended_hwdesc = true,
1562        .plane_f0_not_working = true,   /* REVISIT */
1563        .max_width = 4096,
1564        .max_height = 2048,
1565        .max_burst = JZ_LCD_CTRL_BURST_64,
1566        .formats_f1 = jz4770_formats_f1,
1567        .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1),
1568        .formats_f0 = jz4770_formats_f0,
1569        .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0),
1570};
1571
1572static const struct of_device_id ingenic_drm_of_match[] = {
1573        { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info },
1574        { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info },
1575        { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info },
1576        { .compatible = "ingenic,jz4780-lcd", .data = &jz4780_soc_info },
1577        { /* sentinel */ },
1578};
1579MODULE_DEVICE_TABLE(of, ingenic_drm_of_match);
1580
1581static struct platform_driver ingenic_drm_driver = {
1582        .driver = {
1583                .name = "ingenic-drm",
1584                .pm = pm_ptr(&ingenic_drm_pm_ops),
1585                .of_match_table = of_match_ptr(ingenic_drm_of_match),
1586        },
1587        .probe = ingenic_drm_probe,
1588        .remove = ingenic_drm_remove,
1589};
1590
1591static int ingenic_drm_init(void)
1592{
1593        int err;
1594
1595        if (drm_firmware_drivers_only())
1596                return -ENODEV;
1597
1598        if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) {
1599                err = platform_driver_register(ingenic_ipu_driver_ptr);
1600                if (err)
1601                        return err;
1602        }
1603
1604        return platform_driver_register(&ingenic_drm_driver);
1605}
1606module_init(ingenic_drm_init);
1607
1608static void ingenic_drm_exit(void)
1609{
1610        platform_driver_unregister(&ingenic_drm_driver);
1611
1612        if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU))
1613                platform_driver_unregister(ingenic_ipu_driver_ptr);
1614}
1615module_exit(ingenic_drm_exit);
1616
1617MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
1618MODULE_DESCRIPTION("DRM driver for the Ingenic SoCs\n");
1619MODULE_LICENSE("GPL v2");
1620