linux/drivers/gpu/drm/arm/malidp_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
   4 * Author: Liviu Dudau <Liviu.Dudau@arm.com>
   5 *
   6 * ARM Mali DP500/DP550/DP650 KMS/DRM driver
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/clk.h>
  11#include <linux/component.h>
  12#include <linux/of_device.h>
  13#include <linux/of_graph.h>
  14#include <linux/of_reserved_mem.h>
  15#include <linux/pm_runtime.h>
  16#include <linux/debugfs.h>
  17
  18#include <drm/drmP.h>
  19#include <drm/drm_atomic.h>
  20#include <drm/drm_atomic_helper.h>
  21#include <drm/drm_crtc.h>
  22#include <drm/drm_probe_helper.h>
  23#include <drm/drm_fb_helper.h>
  24#include <drm/drm_fb_cma_helper.h>
  25#include <drm/drm_gem_cma_helper.h>
  26#include <drm/drm_gem_framebuffer_helper.h>
  27#include <drm/drm_modeset_helper.h>
  28#include <drm/drm_of.h>
  29
  30#include "malidp_drv.h"
  31#include "malidp_mw.h"
  32#include "malidp_regs.h"
  33#include "malidp_hw.h"
  34
  35#define MALIDP_CONF_VALID_TIMEOUT       250
  36#define AFBC_HEADER_SIZE                16
  37#define AFBC_SUPERBLK_ALIGNMENT         128
  38
  39static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
  40                                     u32 data[MALIDP_COEFFTAB_NUM_COEFFS])
  41{
  42        int i;
  43        /* Update all channels with a single gamma curve. */
  44        const u32 gamma_write_mask = GENMASK(18, 16);
  45        /*
  46         * Always write an entire table, so the address field in
  47         * DE_COEFFTAB_ADDR is 0 and we can use the gamma_write_mask bitmask
  48         * directly.
  49         */
  50        malidp_hw_write(hwdev, gamma_write_mask,
  51                        hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR);
  52        for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i)
  53                malidp_hw_write(hwdev, data[i],
  54                                hwdev->hw->map.coeffs_base +
  55                                MALIDP_COEF_TABLE_DATA);
  56}
  57
  58static void malidp_atomic_commit_update_gamma(struct drm_crtc *crtc,
  59                                              struct drm_crtc_state *old_state)
  60{
  61        struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
  62        struct malidp_hw_device *hwdev = malidp->dev;
  63
  64        if (!crtc->state->color_mgmt_changed)
  65                return;
  66
  67        if (!crtc->state->gamma_lut) {
  68                malidp_hw_clearbits(hwdev,
  69                                    MALIDP_DISP_FUNC_GAMMA,
  70                                    MALIDP_DE_DISPLAY_FUNC);
  71        } else {
  72                struct malidp_crtc_state *mc =
  73                        to_malidp_crtc_state(crtc->state);
  74
  75                if (!old_state->gamma_lut || (crtc->state->gamma_lut->base.id !=
  76                                              old_state->gamma_lut->base.id))
  77                        malidp_write_gamma_table(hwdev, mc->gamma_coeffs);
  78
  79                malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_GAMMA,
  80                                  MALIDP_DE_DISPLAY_FUNC);
  81        }
  82}
  83
  84static
  85void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
  86                                          struct drm_crtc_state *old_state)
  87{
  88        struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
  89        struct malidp_hw_device *hwdev = malidp->dev;
  90        int i;
  91
  92        if (!crtc->state->color_mgmt_changed)
  93                return;
  94
  95        if (!crtc->state->ctm) {
  96                malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_CADJ,
  97                                    MALIDP_DE_DISPLAY_FUNC);
  98        } else {
  99                struct malidp_crtc_state *mc =
 100                        to_malidp_crtc_state(crtc->state);
 101
 102                if (!old_state->ctm || (crtc->state->ctm->base.id !=
 103                                        old_state->ctm->base.id))
 104                        for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
 105                                malidp_hw_write(hwdev,
 106                                                mc->coloradj_coeffs[i],
 107                                                hwdev->hw->map.coeffs_base +
 108                                                MALIDP_COLOR_ADJ_COEF + 4 * i);
 109
 110                malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
 111                                  MALIDP_DE_DISPLAY_FUNC);
 112        }
 113}
 114
 115static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
 116                                           struct drm_crtc_state *old_state)
 117{
 118        struct malidp_crtc_state *cs = to_malidp_crtc_state(crtc->state);
 119        struct malidp_crtc_state *old_cs = to_malidp_crtc_state(old_state);
 120        struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
 121        struct malidp_hw_device *hwdev = malidp->dev;
 122        struct malidp_se_config *s = &cs->scaler_config;
 123        struct malidp_se_config *old_s = &old_cs->scaler_config;
 124        u32 se_control = hwdev->hw->map.se_base +
 125                         ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
 126                         0x10 : 0xC);
 127        u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL;
 128        u32 scr = se_control + MALIDP_SE_SCALING_CONTROL;
 129        u32 val;
 130
 131        /* Set SE_CONTROL */
 132        if (!s->scale_enable) {
 133                val = malidp_hw_read(hwdev, se_control);
 134                val &= ~MALIDP_SE_SCALING_EN;
 135                malidp_hw_write(hwdev, val, se_control);
 136                return;
 137        }
 138
 139        hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s);
 140        val = malidp_hw_read(hwdev, se_control);
 141        val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN;
 142
 143        val &= ~MALIDP_SE_ENH(MALIDP_SE_ENH_MASK);
 144        val |= s->enhancer_enable ? MALIDP_SE_ENH(3) : 0;
 145
 146        val |= MALIDP_SE_RGBO_IF_EN;
 147        malidp_hw_write(hwdev, val, se_control);
 148
 149        /* Set IN_SIZE & OUT_SIZE. */
 150        val = MALIDP_SE_SET_V_SIZE(s->input_h) |
 151              MALIDP_SE_SET_H_SIZE(s->input_w);
 152        malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_IN_SIZE);
 153        val = MALIDP_SE_SET_V_SIZE(s->output_h) |
 154              MALIDP_SE_SET_H_SIZE(s->output_w);
 155        malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_OUT_SIZE);
 156
 157        /* Set phase regs. */
 158        malidp_hw_write(hwdev, s->h_init_phase, scr + MALIDP_SE_H_INIT_PH);
 159        malidp_hw_write(hwdev, s->h_delta_phase, scr + MALIDP_SE_H_DELTA_PH);
 160        malidp_hw_write(hwdev, s->v_init_phase, scr + MALIDP_SE_V_INIT_PH);
 161        malidp_hw_write(hwdev, s->v_delta_phase, scr + MALIDP_SE_V_DELTA_PH);
 162}
 163
 164/*
 165 * set the "config valid" bit and wait until the hardware acts on it
 166 */
 167static int malidp_set_and_wait_config_valid(struct drm_device *drm)
 168{
 169        struct malidp_drm *malidp = drm->dev_private;
 170        struct malidp_hw_device *hwdev = malidp->dev;
 171        int ret;
 172
 173        hwdev->hw->set_config_valid(hwdev, 1);
 174        /* don't wait for config_valid flag if we are in config mode */
 175        if (hwdev->hw->in_config_mode(hwdev)) {
 176                atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_DONE);
 177                return 0;
 178        }
 179
 180        ret = wait_event_interruptible_timeout(malidp->wq,
 181                        atomic_read(&malidp->config_valid) == MALIDP_CONFIG_VALID_DONE,
 182                        msecs_to_jiffies(MALIDP_CONF_VALID_TIMEOUT));
 183
 184        return (ret > 0) ? 0 : -ETIMEDOUT;
 185}
 186
 187static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
 188{
 189        struct drm_device *drm = state->dev;
 190        struct malidp_drm *malidp = drm->dev_private;
 191        int loop = 5;
 192
 193        malidp->event = malidp->crtc.state->event;
 194        malidp->crtc.state->event = NULL;
 195
 196        if (malidp->crtc.state->active) {
 197                /*
 198                 * if we have an event to deliver to userspace, make sure
 199                 * the vblank is enabled as we are sending it from the IRQ
 200                 * handler.
 201                 */
 202                if (malidp->event)
 203                        drm_crtc_vblank_get(&malidp->crtc);
 204
 205                /* only set config_valid if the CRTC is enabled */
 206                if (malidp_set_and_wait_config_valid(drm) < 0) {
 207                        /*
 208                         * make a loop around the second CVAL setting and
 209                         * try 5 times before giving up.
 210                         */
 211                        while (loop--) {
 212                                if (!malidp_set_and_wait_config_valid(drm))
 213                                        break;
 214                        }
 215                        DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n");
 216                }
 217
 218        } else if (malidp->event) {
 219                /* CRTC inactive means vblank IRQ is disabled, send event directly */
 220                spin_lock_irq(&drm->event_lock);
 221                drm_crtc_send_vblank_event(&malidp->crtc, malidp->event);
 222                malidp->event = NULL;
 223                spin_unlock_irq(&drm->event_lock);
 224        }
 225        drm_atomic_helper_commit_hw_done(state);
 226}
 227
 228static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
 229{
 230        struct drm_device *drm = state->dev;
 231        struct malidp_drm *malidp = drm->dev_private;
 232        struct drm_crtc *crtc;
 233        struct drm_crtc_state *old_crtc_state;
 234        int i;
 235
 236        pm_runtime_get_sync(drm->dev);
 237
 238        /*
 239         * set config_valid to a special value to let IRQ handlers
 240         * know that we are updating registers
 241         */
 242        atomic_set(&malidp->config_valid, MALIDP_CONFIG_START);
 243        malidp->dev->hw->set_config_valid(malidp->dev, 0);
 244
 245        drm_atomic_helper_commit_modeset_disables(drm, state);
 246
 247        for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
 248                malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
 249                malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
 250                malidp_atomic_commit_se_config(crtc, old_crtc_state);
 251        }
 252
 253        drm_atomic_helper_commit_planes(drm, state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
 254
 255        malidp_mw_atomic_commit(drm, state);
 256
 257        drm_atomic_helper_commit_modeset_enables(drm, state);
 258
 259        malidp_atomic_commit_hw_done(state);
 260
 261        pm_runtime_put(drm->dev);
 262
 263        drm_atomic_helper_cleanup_planes(drm, state);
 264}
 265
 266static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = {
 267        .atomic_commit_tail = malidp_atomic_commit_tail,
 268};
 269
 270static bool
 271malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
 272                                    const struct drm_mode_fb_cmd2 *mode_cmd)
 273{
 274        if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
 275                                        mode_cmd->modifier[0]) == false)
 276                return false;
 277
 278        if (mode_cmd->offsets[0] != 0) {
 279                DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
 280                return false;
 281        }
 282
 283        switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
 284        case AFBC_SIZE_16X16:
 285                if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
 286                        DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 pixels\n");
 287                        return false;
 288                }
 289                break;
 290        default:
 291                DRM_DEBUG_KMS("Unsupported AFBC block size\n");
 292                return false;
 293        }
 294
 295        return true;
 296}
 297
 298static bool
 299malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
 300                                    struct drm_file *file,
 301                                    const struct drm_mode_fb_cmd2 *mode_cmd)
 302{
 303        int n_superblocks = 0;
 304        const struct drm_format_info *info;
 305        struct drm_gem_object *objs = NULL;
 306        u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
 307        u32 afbc_superblock_width = 0, afbc_size = 0;
 308        int bpp = 0;
 309
 310        switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
 311        case AFBC_SIZE_16X16:
 312                afbc_superblock_height = 16;
 313                afbc_superblock_width = 16;
 314                break;
 315        default:
 316                DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
 317                return false;
 318        }
 319
 320        info = drm_get_format_info(dev, mode_cmd);
 321
 322        n_superblocks = (mode_cmd->width / afbc_superblock_width) *
 323                (mode_cmd->height / afbc_superblock_height);
 324
 325        bpp = malidp_format_get_bpp(info->format);
 326
 327        afbc_superblock_size = (bpp * afbc_superblock_width * afbc_superblock_height)
 328                                / BITS_PER_BYTE;
 329
 330        afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE, AFBC_SUPERBLK_ALIGNMENT);
 331        afbc_size += n_superblocks * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
 332
 333        if ((mode_cmd->width * bpp) != (mode_cmd->pitches[0] * BITS_PER_BYTE)) {
 334                DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) (=%u) "
 335                              "should be same as width (=%u) * bpp (=%u)\n",
 336                              (mode_cmd->pitches[0] * BITS_PER_BYTE),
 337                              mode_cmd->width, bpp);
 338                return false;
 339        }
 340
 341        objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
 342        if (!objs) {
 343                DRM_DEBUG_KMS("Failed to lookup GEM object\n");
 344                return false;
 345        }
 346
 347        if (objs->size < afbc_size) {
 348                DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC buffer size = %u\n",
 349                              objs->size, afbc_size);
 350                drm_gem_object_put_unlocked(objs);
 351                return false;
 352        }
 353
 354        drm_gem_object_put_unlocked(objs);
 355
 356        return true;
 357}
 358
 359static bool
 360malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
 361                               const struct drm_mode_fb_cmd2 *mode_cmd)
 362{
 363        if (malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
 364                return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
 365
 366        return false;
 367}
 368
 369struct drm_framebuffer *
 370malidp_fb_create(struct drm_device *dev, struct drm_file *file,
 371                 const struct drm_mode_fb_cmd2 *mode_cmd)
 372{
 373        if (mode_cmd->modifier[0]) {
 374                if (!malidp_verify_afbc_framebuffer(dev, file, mode_cmd))
 375                        return ERR_PTR(-EINVAL);
 376        }
 377
 378        return drm_gem_fb_create(dev, file, mode_cmd);
 379}
 380
 381static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
 382        .fb_create = malidp_fb_create,
 383        .atomic_check = drm_atomic_helper_check,
 384        .atomic_commit = drm_atomic_helper_commit,
 385};
 386
 387static int malidp_init(struct drm_device *drm)
 388{
 389        int ret;
 390        struct malidp_drm *malidp = drm->dev_private;
 391        struct malidp_hw_device *hwdev = malidp->dev;
 392
 393        drm_mode_config_init(drm);
 394
 395        drm->mode_config.min_width = hwdev->min_line_size;
 396        drm->mode_config.min_height = hwdev->min_line_size;
 397        drm->mode_config.max_width = hwdev->max_line_size;
 398        drm->mode_config.max_height = hwdev->max_line_size;
 399        drm->mode_config.funcs = &malidp_mode_config_funcs;
 400        drm->mode_config.helper_private = &malidp_mode_config_helpers;
 401        drm->mode_config.allow_fb_modifiers = true;
 402
 403        ret = malidp_crtc_init(drm);
 404        if (ret)
 405                goto crtc_fail;
 406
 407        ret = malidp_mw_connector_init(drm);
 408        if (ret)
 409                goto crtc_fail;
 410
 411        return 0;
 412
 413crtc_fail:
 414        drm_mode_config_cleanup(drm);
 415        return ret;
 416}
 417
 418static void malidp_fini(struct drm_device *drm)
 419{
 420        drm_mode_config_cleanup(drm);
 421}
 422
 423static int malidp_irq_init(struct platform_device *pdev)
 424{
 425        int irq_de, irq_se, ret = 0;
 426        struct drm_device *drm = dev_get_drvdata(&pdev->dev);
 427        struct malidp_drm *malidp = drm->dev_private;
 428        struct malidp_hw_device *hwdev = malidp->dev;
 429
 430        /* fetch the interrupts from DT */
 431        irq_de = platform_get_irq_byname(pdev, "DE");
 432        if (irq_de < 0) {
 433                DRM_ERROR("no 'DE' IRQ specified!\n");
 434                return irq_de;
 435        }
 436        irq_se = platform_get_irq_byname(pdev, "SE");
 437        if (irq_se < 0) {
 438                DRM_ERROR("no 'SE' IRQ specified!\n");
 439                return irq_se;
 440        }
 441
 442        ret = malidp_de_irq_init(drm, irq_de);
 443        if (ret)
 444                return ret;
 445
 446        ret = malidp_se_irq_init(drm, irq_se);
 447        if (ret) {
 448                malidp_de_irq_fini(hwdev);
 449                return ret;
 450        }
 451
 452        return 0;
 453}
 454
 455DEFINE_DRM_GEM_CMA_FOPS(fops);
 456
 457static int malidp_dumb_create(struct drm_file *file_priv,
 458                              struct drm_device *drm,
 459                              struct drm_mode_create_dumb *args)
 460{
 461        struct malidp_drm *malidp = drm->dev_private;
 462        /* allocate for the worst case scenario, i.e. rotated buffers */
 463        u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1);
 464
 465        args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), alignment);
 466
 467        return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
 468}
 469
 470#ifdef CONFIG_DEBUG_FS
 471
 472static void malidp_error_stats_init(struct malidp_error_stats *error_stats)
 473{
 474        error_stats->num_errors = 0;
 475        error_stats->last_error_status = 0;
 476        error_stats->last_error_vblank = -1;
 477}
 478
 479void malidp_error(struct malidp_drm *malidp,
 480                  struct malidp_error_stats *error_stats, u32 status,
 481                  u64 vblank)
 482{
 483        unsigned long irqflags;
 484
 485        spin_lock_irqsave(&malidp->errors_lock, irqflags);
 486        error_stats->last_error_status = status;
 487        error_stats->last_error_vblank = vblank;
 488        error_stats->num_errors++;
 489        spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
 490}
 491
 492void malidp_error_stats_dump(const char *prefix,
 493                             struct malidp_error_stats error_stats,
 494                             struct seq_file *m)
 495{
 496        seq_printf(m, "[%s] num_errors : %d\n", prefix,
 497                   error_stats.num_errors);
 498        seq_printf(m, "[%s] last_error_status  : 0x%08x\n", prefix,
 499                   error_stats.last_error_status);
 500        seq_printf(m, "[%s] last_error_vblank : %lld\n", prefix,
 501                   error_stats.last_error_vblank);
 502}
 503
 504static int malidp_show_stats(struct seq_file *m, void *arg)
 505{
 506        struct drm_device *drm = m->private;
 507        struct malidp_drm *malidp = drm->dev_private;
 508        unsigned long irqflags;
 509        struct malidp_error_stats de_errors, se_errors;
 510
 511        spin_lock_irqsave(&malidp->errors_lock, irqflags);
 512        de_errors = malidp->de_errors;
 513        se_errors = malidp->se_errors;
 514        spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
 515        malidp_error_stats_dump("DE", de_errors, m);
 516        malidp_error_stats_dump("SE", se_errors, m);
 517        return 0;
 518}
 519
 520static int malidp_debugfs_open(struct inode *inode, struct file *file)
 521{
 522        return single_open(file, malidp_show_stats, inode->i_private);
 523}
 524
 525static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
 526                                    size_t len, loff_t *offp)
 527{
 528        struct seq_file *m = file->private_data;
 529        struct drm_device *drm = m->private;
 530        struct malidp_drm *malidp = drm->dev_private;
 531        unsigned long irqflags;
 532
 533        spin_lock_irqsave(&malidp->errors_lock, irqflags);
 534        malidp_error_stats_init(&malidp->de_errors);
 535        malidp_error_stats_init(&malidp->se_errors);
 536        spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
 537        return len;
 538}
 539
 540static const struct file_operations malidp_debugfs_fops = {
 541        .owner = THIS_MODULE,
 542        .open = malidp_debugfs_open,
 543        .read = seq_read,
 544        .write = malidp_debugfs_write,
 545        .llseek = seq_lseek,
 546        .release = single_release,
 547};
 548
 549static int malidp_debugfs_init(struct drm_minor *minor)
 550{
 551        struct malidp_drm *malidp = minor->dev->dev_private;
 552
 553        malidp_error_stats_init(&malidp->de_errors);
 554        malidp_error_stats_init(&malidp->se_errors);
 555        spin_lock_init(&malidp->errors_lock);
 556        debugfs_create_file("debug", S_IRUGO | S_IWUSR, minor->debugfs_root,
 557                            minor->dev, &malidp_debugfs_fops);
 558        return 0;
 559}
 560
 561#endif //CONFIG_DEBUG_FS
 562
 563static struct drm_driver malidp_driver = {
 564        .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
 565                           DRIVER_PRIME,
 566        .gem_free_object_unlocked = drm_gem_cma_free_object,
 567        .gem_vm_ops = &drm_gem_cma_vm_ops,
 568        .dumb_create = malidp_dumb_create,
 569        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 570        .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 571        .gem_prime_export = drm_gem_prime_export,
 572        .gem_prime_import = drm_gem_prime_import,
 573        .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
 574        .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
 575        .gem_prime_vmap = drm_gem_cma_prime_vmap,
 576        .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
 577        .gem_prime_mmap = drm_gem_cma_prime_mmap,
 578#ifdef CONFIG_DEBUG_FS
 579        .debugfs_init = malidp_debugfs_init,
 580#endif
 581        .fops = &fops,
 582        .name = "mali-dp",
 583        .desc = "ARM Mali Display Processor driver",
 584        .date = "20160106",
 585        .major = 1,
 586        .minor = 0,
 587};
 588
 589static const struct of_device_id  malidp_drm_of_match[] = {
 590        {
 591                .compatible = "arm,mali-dp500",
 592                .data = &malidp_device[MALIDP_500]
 593        },
 594        {
 595                .compatible = "arm,mali-dp550",
 596                .data = &malidp_device[MALIDP_550]
 597        },
 598        {
 599                .compatible = "arm,mali-dp650",
 600                .data = &malidp_device[MALIDP_650]
 601        },
 602        {},
 603};
 604MODULE_DEVICE_TABLE(of, malidp_drm_of_match);
 605
 606static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev,
 607                                       const struct of_device_id *dev_id)
 608{
 609        u32 core_id;
 610        const char *compatstr_dp500 = "arm,mali-dp500";
 611        bool is_dp500;
 612        bool dt_is_dp500;
 613
 614        /*
 615         * The DP500 CORE_ID register is in a different location, so check it
 616         * first. If the product id field matches, then this is DP500, otherwise
 617         * check the DP550/650 CORE_ID register.
 618         */
 619        core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID);
 620        /* Offset 0x18 will never read 0x500 on products other than DP500. */
 621        is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500);
 622        dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500,
 623                              sizeof(dev_id->compatible)) != NULL;
 624        if (is_dp500 != dt_is_dp500) {
 625                DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n",
 626                          dev_id->compatible, is_dp500 ? "is" : "is not");
 627                return false;
 628        } else if (!dt_is_dp500) {
 629                u16 product_id;
 630                char buf[32];
 631
 632                core_id = malidp_hw_read(hwdev,
 633                                         MALIDP550_DC_BASE + MALIDP_DE_CORE_ID);
 634                product_id = MALIDP_PRODUCT_ID(core_id);
 635                snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id);
 636                if (!strnstr(dev_id->compatible, buf,
 637                             sizeof(dev_id->compatible))) {
 638                        DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n",
 639                                  dev_id->compatible, product_id);
 640                        return false;
 641                }
 642        }
 643        return true;
 644}
 645
 646static bool malidp_has_sufficient_address_space(const struct resource *res,
 647                                                const struct of_device_id *dev_id)
 648{
 649        resource_size_t res_size = resource_size(res);
 650        const char *compatstr_dp500 = "arm,mali-dp500";
 651
 652        if (!strnstr(dev_id->compatible, compatstr_dp500,
 653                     sizeof(dev_id->compatible)))
 654                return res_size >= MALIDP550_ADDR_SPACE_SIZE;
 655        else if (res_size < MALIDP500_ADDR_SPACE_SIZE)
 656                return false;
 657        return true;
 658}
 659
 660static ssize_t core_id_show(struct device *dev, struct device_attribute *attr,
 661                            char *buf)
 662{
 663        struct drm_device *drm = dev_get_drvdata(dev);
 664        struct malidp_drm *malidp = drm->dev_private;
 665
 666        return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
 667}
 668
 669DEVICE_ATTR_RO(core_id);
 670
 671static int malidp_init_sysfs(struct device *dev)
 672{
 673        int ret = device_create_file(dev, &dev_attr_core_id);
 674
 675        if (ret)
 676                DRM_ERROR("failed to create device file for core_id\n");
 677
 678        return ret;
 679}
 680
 681static void malidp_fini_sysfs(struct device *dev)
 682{
 683        device_remove_file(dev, &dev_attr_core_id);
 684}
 685
 686#define MAX_OUTPUT_CHANNELS     3
 687
 688static int malidp_runtime_pm_suspend(struct device *dev)
 689{
 690        struct drm_device *drm = dev_get_drvdata(dev);
 691        struct malidp_drm *malidp = drm->dev_private;
 692        struct malidp_hw_device *hwdev = malidp->dev;
 693
 694        /* we can only suspend if the hardware is in config mode */
 695        WARN_ON(!hwdev->hw->in_config_mode(hwdev));
 696
 697        malidp_se_irq_fini(hwdev);
 698        malidp_de_irq_fini(hwdev);
 699        hwdev->pm_suspended = true;
 700        clk_disable_unprepare(hwdev->mclk);
 701        clk_disable_unprepare(hwdev->aclk);
 702        clk_disable_unprepare(hwdev->pclk);
 703
 704        return 0;
 705}
 706
 707static int malidp_runtime_pm_resume(struct device *dev)
 708{
 709        struct drm_device *drm = dev_get_drvdata(dev);
 710        struct malidp_drm *malidp = drm->dev_private;
 711        struct malidp_hw_device *hwdev = malidp->dev;
 712
 713        clk_prepare_enable(hwdev->pclk);
 714        clk_prepare_enable(hwdev->aclk);
 715        clk_prepare_enable(hwdev->mclk);
 716        hwdev->pm_suspended = false;
 717        malidp_de_irq_hw_init(hwdev);
 718        malidp_se_irq_hw_init(hwdev);
 719
 720        return 0;
 721}
 722
 723static int malidp_bind(struct device *dev)
 724{
 725        struct resource *res;
 726        struct drm_device *drm;
 727        struct malidp_drm *malidp;
 728        struct malidp_hw_device *hwdev;
 729        struct platform_device *pdev = to_platform_device(dev);
 730        struct of_device_id const *dev_id;
 731        struct drm_encoder *encoder;
 732        /* number of lines for the R, G and B output */
 733        u8 output_width[MAX_OUTPUT_CHANNELS];
 734        int ret = 0, i;
 735        u32 version, out_depth = 0;
 736
 737        malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL);
 738        if (!malidp)
 739                return -ENOMEM;
 740
 741        hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL);
 742        if (!hwdev)
 743                return -ENOMEM;
 744
 745        hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
 746        malidp->dev = hwdev;
 747
 748        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 749        hwdev->regs = devm_ioremap_resource(dev, res);
 750        if (IS_ERR(hwdev->regs))
 751                return PTR_ERR(hwdev->regs);
 752
 753        hwdev->pclk = devm_clk_get(dev, "pclk");
 754        if (IS_ERR(hwdev->pclk))
 755                return PTR_ERR(hwdev->pclk);
 756
 757        hwdev->aclk = devm_clk_get(dev, "aclk");
 758        if (IS_ERR(hwdev->aclk))
 759                return PTR_ERR(hwdev->aclk);
 760
 761        hwdev->mclk = devm_clk_get(dev, "mclk");
 762        if (IS_ERR(hwdev->mclk))
 763                return PTR_ERR(hwdev->mclk);
 764
 765        hwdev->pxlclk = devm_clk_get(dev, "pxlclk");
 766        if (IS_ERR(hwdev->pxlclk))
 767                return PTR_ERR(hwdev->pxlclk);
 768
 769        /* Get the optional framebuffer memory resource */
 770        ret = of_reserved_mem_device_init(dev);
 771        if (ret && ret != -ENODEV)
 772                return ret;
 773
 774        drm = drm_dev_alloc(&malidp_driver, dev);
 775        if (IS_ERR(drm)) {
 776                ret = PTR_ERR(drm);
 777                goto alloc_fail;
 778        }
 779
 780        drm->dev_private = malidp;
 781        dev_set_drvdata(dev, drm);
 782
 783        /* Enable power management */
 784        pm_runtime_enable(dev);
 785
 786        /* Resume device to enable the clocks */
 787        if (pm_runtime_enabled(dev))
 788                pm_runtime_get_sync(dev);
 789        else
 790                malidp_runtime_pm_resume(dev);
 791
 792        dev_id = of_match_device(malidp_drm_of_match, dev);
 793        if (!dev_id) {
 794                ret = -EINVAL;
 795                goto query_hw_fail;
 796        }
 797
 798        if (!malidp_has_sufficient_address_space(res, dev_id)) {
 799                DRM_ERROR("Insufficient address space in device-tree.\n");
 800                ret = -EINVAL;
 801                goto query_hw_fail;
 802        }
 803
 804        if (!malidp_is_compatible_hw_id(hwdev, dev_id)) {
 805                ret = -EINVAL;
 806                goto query_hw_fail;
 807        }
 808
 809        ret = hwdev->hw->query_hw(hwdev);
 810        if (ret) {
 811                DRM_ERROR("Invalid HW configuration\n");
 812                goto query_hw_fail;
 813        }
 814
 815        version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID);
 816        DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16,
 817                 (version >> 12) & 0xf, (version >> 8) & 0xf);
 818
 819        malidp->core_id = version;
 820
 821        /* set the number of lines used for output of RGB data */
 822        ret = of_property_read_u8_array(dev->of_node,
 823                                        "arm,malidp-output-port-lines",
 824                                        output_width, MAX_OUTPUT_CHANNELS);
 825        if (ret)
 826                goto query_hw_fail;
 827
 828        for (i = 0; i < MAX_OUTPUT_CHANNELS; i++)
 829                out_depth = (out_depth << 8) | (output_width[i] & 0xf);
 830        malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base);
 831        hwdev->output_color_depth = out_depth;
 832
 833        atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_INIT);
 834        init_waitqueue_head(&malidp->wq);
 835
 836        ret = malidp_init(drm);
 837        if (ret < 0)
 838                goto query_hw_fail;
 839
 840        ret = malidp_init_sysfs(dev);
 841        if (ret)
 842                goto init_fail;
 843
 844        /* Set the CRTC's port so that the encoder component can find it */
 845        malidp->crtc.port = of_graph_get_port_by_id(dev->of_node, 0);
 846
 847        ret = component_bind_all(dev, drm);
 848        if (ret) {
 849                DRM_ERROR("Failed to bind all components\n");
 850                goto bind_fail;
 851        }
 852
 853        /* We expect to have a maximum of two encoders one for the actual
 854         * display and a virtual one for the writeback connector
 855         */
 856        WARN_ON(drm->mode_config.num_encoder > 2);
 857        list_for_each_entry(encoder, &drm->mode_config.encoder_list, head) {
 858                encoder->possible_clones =
 859                                (1 << drm->mode_config.num_encoder) -  1;
 860        }
 861
 862        ret = malidp_irq_init(pdev);
 863        if (ret < 0)
 864                goto irq_init_fail;
 865
 866        drm->irq_enabled = true;
 867
 868        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 869        drm_crtc_vblank_reset(&malidp->crtc);
 870        if (ret < 0) {
 871                DRM_ERROR("failed to initialise vblank\n");
 872                goto vblank_fail;
 873        }
 874        pm_runtime_put(dev);
 875
 876        drm_mode_config_reset(drm);
 877
 878        drm_kms_helper_poll_init(drm);
 879
 880        ret = drm_dev_register(drm, 0);
 881        if (ret)
 882                goto register_fail;
 883
 884        drm_fbdev_generic_setup(drm, 32);
 885
 886        return 0;
 887
 888register_fail:
 889        drm_kms_helper_poll_fini(drm);
 890        pm_runtime_get_sync(dev);
 891vblank_fail:
 892        malidp_se_irq_fini(hwdev);
 893        malidp_de_irq_fini(hwdev);
 894        drm->irq_enabled = false;
 895irq_init_fail:
 896        drm_atomic_helper_shutdown(drm);
 897        component_unbind_all(dev, drm);
 898bind_fail:
 899        of_node_put(malidp->crtc.port);
 900        malidp->crtc.port = NULL;
 901init_fail:
 902        malidp_fini_sysfs(dev);
 903        malidp_fini(drm);
 904query_hw_fail:
 905        pm_runtime_put(dev);
 906        if (pm_runtime_enabled(dev))
 907                pm_runtime_disable(dev);
 908        else
 909                malidp_runtime_pm_suspend(dev);
 910        drm->dev_private = NULL;
 911        dev_set_drvdata(dev, NULL);
 912        drm_dev_put(drm);
 913alloc_fail:
 914        of_reserved_mem_device_release(dev);
 915
 916        return ret;
 917}
 918
 919static void malidp_unbind(struct device *dev)
 920{
 921        struct drm_device *drm = dev_get_drvdata(dev);
 922        struct malidp_drm *malidp = drm->dev_private;
 923        struct malidp_hw_device *hwdev = malidp->dev;
 924
 925        drm_dev_unregister(drm);
 926        drm_kms_helper_poll_fini(drm);
 927        pm_runtime_get_sync(dev);
 928        drm_crtc_vblank_off(&malidp->crtc);
 929        malidp_se_irq_fini(hwdev);
 930        malidp_de_irq_fini(hwdev);
 931        drm->irq_enabled = false;
 932        drm_atomic_helper_shutdown(drm);
 933        component_unbind_all(dev, drm);
 934        of_node_put(malidp->crtc.port);
 935        malidp->crtc.port = NULL;
 936        malidp_fini_sysfs(dev);
 937        malidp_fini(drm);
 938        pm_runtime_put(dev);
 939        if (pm_runtime_enabled(dev))
 940                pm_runtime_disable(dev);
 941        else
 942                malidp_runtime_pm_suspend(dev);
 943        drm->dev_private = NULL;
 944        dev_set_drvdata(dev, NULL);
 945        drm_dev_put(drm);
 946        of_reserved_mem_device_release(dev);
 947}
 948
 949static const struct component_master_ops malidp_master_ops = {
 950        .bind = malidp_bind,
 951        .unbind = malidp_unbind,
 952};
 953
 954static int malidp_compare_dev(struct device *dev, void *data)
 955{
 956        struct device_node *np = data;
 957
 958        return dev->of_node == np;
 959}
 960
 961static int malidp_platform_probe(struct platform_device *pdev)
 962{
 963        struct device_node *port;
 964        struct component_match *match = NULL;
 965
 966        if (!pdev->dev.of_node)
 967                return -ENODEV;
 968
 969        /* there is only one output port inside each device, find it */
 970        port = of_graph_get_remote_node(pdev->dev.of_node, 0, 0);
 971        if (!port)
 972                return -ENODEV;
 973
 974        drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev,
 975                                   port);
 976        of_node_put(port);
 977        return component_master_add_with_match(&pdev->dev, &malidp_master_ops,
 978                                               match);
 979}
 980
 981static int malidp_platform_remove(struct platform_device *pdev)
 982{
 983        component_master_del(&pdev->dev, &malidp_master_ops);
 984        return 0;
 985}
 986
 987static int __maybe_unused malidp_pm_suspend(struct device *dev)
 988{
 989        struct drm_device *drm = dev_get_drvdata(dev);
 990
 991        return drm_mode_config_helper_suspend(drm);
 992}
 993
 994static int __maybe_unused malidp_pm_resume(struct device *dev)
 995{
 996        struct drm_device *drm = dev_get_drvdata(dev);
 997
 998        drm_mode_config_helper_resume(drm);
 999
1000        return 0;
1001}
1002
1003static int __maybe_unused malidp_pm_suspend_late(struct device *dev)
1004{
1005        if (!pm_runtime_status_suspended(dev)) {
1006                malidp_runtime_pm_suspend(dev);
1007                pm_runtime_set_suspended(dev);
1008        }
1009        return 0;
1010}
1011
1012static int __maybe_unused malidp_pm_resume_early(struct device *dev)
1013{
1014        malidp_runtime_pm_resume(dev);
1015        pm_runtime_set_active(dev);
1016        return 0;
1017}
1018
1019static const struct dev_pm_ops malidp_pm_ops = {
1020        SET_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend, malidp_pm_resume) \
1021        SET_LATE_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend_late, malidp_pm_resume_early) \
1022        SET_RUNTIME_PM_OPS(malidp_runtime_pm_suspend, malidp_runtime_pm_resume, NULL)
1023};
1024
1025static struct platform_driver malidp_platform_driver = {
1026        .probe          = malidp_platform_probe,
1027        .remove         = malidp_platform_remove,
1028        .driver = {
1029                .name = "mali-dp",
1030                .pm = &malidp_pm_ops,
1031                .of_match_table = malidp_drm_of_match,
1032        },
1033};
1034
1035module_platform_driver(malidp_platform_driver);
1036
1037MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
1038MODULE_DESCRIPTION("ARM Mali DP DRM driver");
1039MODULE_LICENSE("GPL v2");
1040