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