Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
0004  * Author: Liviu Dudau <Liviu.Dudau@arm.com>
0005  *
0006  * ARM Mali DP500/DP550/DP650 KMS/DRM driver
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/clk.h>
0011 #include <linux/component.h>
0012 #include <linux/of_device.h>
0013 #include <linux/of_graph.h>
0014 #include <linux/of_reserved_mem.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/debugfs.h>
0017 
0018 #include <drm/drm_atomic.h>
0019 #include <drm/drm_atomic_helper.h>
0020 #include <drm/drm_crtc.h>
0021 #include <drm/drm_drv.h>
0022 #include <drm/drm_fb_cma_helper.h>
0023 #include <drm/drm_fb_helper.h>
0024 #include <drm/drm_fourcc.h>
0025 #include <drm/drm_gem_cma_helper.h>
0026 #include <drm/drm_gem_framebuffer_helper.h>
0027 #include <drm/drm_modeset_helper.h>
0028 #include <drm/drm_module.h>
0029 #include <drm/drm_of.h>
0030 #include <drm/drm_probe_helper.h>
0031 #include <drm/drm_vblank.h>
0032 
0033 #include "malidp_drv.h"
0034 #include "malidp_mw.h"
0035 #include "malidp_regs.h"
0036 #include "malidp_hw.h"
0037 
0038 #define MALIDP_CONF_VALID_TIMEOUT   250
0039 #define AFBC_HEADER_SIZE        16
0040 #define AFBC_SUPERBLK_ALIGNMENT     128
0041 
0042 static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
0043                      u32 data[MALIDP_COEFFTAB_NUM_COEFFS])
0044 {
0045     int i;
0046     /* Update all channels with a single gamma curve. */
0047     const u32 gamma_write_mask = GENMASK(18, 16);
0048     /*
0049      * Always write an entire table, so the address field in
0050      * DE_COEFFTAB_ADDR is 0 and we can use the gamma_write_mask bitmask
0051      * directly.
0052      */
0053     malidp_hw_write(hwdev, gamma_write_mask,
0054             hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR);
0055     for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i)
0056         malidp_hw_write(hwdev, data[i],
0057                 hwdev->hw->map.coeffs_base +
0058                 MALIDP_COEF_TABLE_DATA);
0059 }
0060 
0061 static void malidp_atomic_commit_update_gamma(struct drm_crtc *crtc,
0062                           struct drm_crtc_state *old_state)
0063 {
0064     struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
0065     struct malidp_hw_device *hwdev = malidp->dev;
0066 
0067     if (!crtc->state->color_mgmt_changed)
0068         return;
0069 
0070     if (!crtc->state->gamma_lut) {
0071         malidp_hw_clearbits(hwdev,
0072                     MALIDP_DISP_FUNC_GAMMA,
0073                     MALIDP_DE_DISPLAY_FUNC);
0074     } else {
0075         struct malidp_crtc_state *mc =
0076             to_malidp_crtc_state(crtc->state);
0077 
0078         if (!old_state->gamma_lut || (crtc->state->gamma_lut->base.id !=
0079                           old_state->gamma_lut->base.id))
0080             malidp_write_gamma_table(hwdev, mc->gamma_coeffs);
0081 
0082         malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_GAMMA,
0083                   MALIDP_DE_DISPLAY_FUNC);
0084     }
0085 }
0086 
0087 static
0088 void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
0089                       struct drm_crtc_state *old_state)
0090 {
0091     struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
0092     struct malidp_hw_device *hwdev = malidp->dev;
0093     int i;
0094 
0095     if (!crtc->state->color_mgmt_changed)
0096         return;
0097 
0098     if (!crtc->state->ctm) {
0099         malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_CADJ,
0100                     MALIDP_DE_DISPLAY_FUNC);
0101     } else {
0102         struct malidp_crtc_state *mc =
0103             to_malidp_crtc_state(crtc->state);
0104 
0105         if (!old_state->ctm || (crtc->state->ctm->base.id !=
0106                     old_state->ctm->base.id))
0107             for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
0108                 malidp_hw_write(hwdev,
0109                         mc->coloradj_coeffs[i],
0110                         hwdev->hw->map.coeffs_base +
0111                         MALIDP_COLOR_ADJ_COEF + 4 * i);
0112 
0113         malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
0114                   MALIDP_DE_DISPLAY_FUNC);
0115     }
0116 }
0117 
0118 static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
0119                        struct drm_crtc_state *old_state)
0120 {
0121     struct malidp_crtc_state *cs = to_malidp_crtc_state(crtc->state);
0122     struct malidp_crtc_state *old_cs = to_malidp_crtc_state(old_state);
0123     struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
0124     struct malidp_hw_device *hwdev = malidp->dev;
0125     struct malidp_se_config *s = &cs->scaler_config;
0126     struct malidp_se_config *old_s = &old_cs->scaler_config;
0127     u32 se_control = hwdev->hw->map.se_base +
0128              ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
0129              0x10 : 0xC);
0130     u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL;
0131     u32 scr = se_control + MALIDP_SE_SCALING_CONTROL;
0132     u32 val;
0133 
0134     /* Set SE_CONTROL */
0135     if (!s->scale_enable) {
0136         val = malidp_hw_read(hwdev, se_control);
0137         val &= ~MALIDP_SE_SCALING_EN;
0138         malidp_hw_write(hwdev, val, se_control);
0139         return;
0140     }
0141 
0142     hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s);
0143     val = malidp_hw_read(hwdev, se_control);
0144     val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN;
0145 
0146     val &= ~MALIDP_SE_ENH(MALIDP_SE_ENH_MASK);
0147     val |= s->enhancer_enable ? MALIDP_SE_ENH(3) : 0;
0148 
0149     val |= MALIDP_SE_RGBO_IF_EN;
0150     malidp_hw_write(hwdev, val, se_control);
0151 
0152     /* Set IN_SIZE & OUT_SIZE. */
0153     val = MALIDP_SE_SET_V_SIZE(s->input_h) |
0154           MALIDP_SE_SET_H_SIZE(s->input_w);
0155     malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_IN_SIZE);
0156     val = MALIDP_SE_SET_V_SIZE(s->output_h) |
0157           MALIDP_SE_SET_H_SIZE(s->output_w);
0158     malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_OUT_SIZE);
0159 
0160     /* Set phase regs. */
0161     malidp_hw_write(hwdev, s->h_init_phase, scr + MALIDP_SE_H_INIT_PH);
0162     malidp_hw_write(hwdev, s->h_delta_phase, scr + MALIDP_SE_H_DELTA_PH);
0163     malidp_hw_write(hwdev, s->v_init_phase, scr + MALIDP_SE_V_INIT_PH);
0164     malidp_hw_write(hwdev, s->v_delta_phase, scr + MALIDP_SE_V_DELTA_PH);
0165 }
0166 
0167 /*
0168  * set the "config valid" bit and wait until the hardware acts on it
0169  */
0170 static int malidp_set_and_wait_config_valid(struct drm_device *drm)
0171 {
0172     struct malidp_drm *malidp = drm->dev_private;
0173     struct malidp_hw_device *hwdev = malidp->dev;
0174     int ret;
0175 
0176     hwdev->hw->set_config_valid(hwdev, 1);
0177     /* don't wait for config_valid flag if we are in config mode */
0178     if (hwdev->hw->in_config_mode(hwdev)) {
0179         atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_DONE);
0180         return 0;
0181     }
0182 
0183     ret = wait_event_interruptible_timeout(malidp->wq,
0184             atomic_read(&malidp->config_valid) == MALIDP_CONFIG_VALID_DONE,
0185             msecs_to_jiffies(MALIDP_CONF_VALID_TIMEOUT));
0186 
0187     return (ret > 0) ? 0 : -ETIMEDOUT;
0188 }
0189 
0190 static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
0191 {
0192     struct drm_device *drm = state->dev;
0193     struct malidp_drm *malidp = drm->dev_private;
0194     int loop = 5;
0195 
0196     malidp->event = malidp->crtc.state->event;
0197     malidp->crtc.state->event = NULL;
0198 
0199     if (malidp->crtc.state->active) {
0200         /*
0201          * if we have an event to deliver to userspace, make sure
0202          * the vblank is enabled as we are sending it from the IRQ
0203          * handler.
0204          */
0205         if (malidp->event)
0206             drm_crtc_vblank_get(&malidp->crtc);
0207 
0208         /* only set config_valid if the CRTC is enabled */
0209         if (malidp_set_and_wait_config_valid(drm) < 0) {
0210             /*
0211              * make a loop around the second CVAL setting and
0212              * try 5 times before giving up.
0213              */
0214             while (loop--) {
0215                 if (!malidp_set_and_wait_config_valid(drm))
0216                     break;
0217             }
0218             DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n");
0219         }
0220 
0221     } else if (malidp->event) {
0222         /* CRTC inactive means vblank IRQ is disabled, send event directly */
0223         spin_lock_irq(&drm->event_lock);
0224         drm_crtc_send_vblank_event(&malidp->crtc, malidp->event);
0225         malidp->event = NULL;
0226         spin_unlock_irq(&drm->event_lock);
0227     }
0228     drm_atomic_helper_commit_hw_done(state);
0229 }
0230 
0231 static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
0232 {
0233     struct drm_device *drm = state->dev;
0234     struct malidp_drm *malidp = drm->dev_private;
0235     struct drm_crtc *crtc;
0236     struct drm_crtc_state *old_crtc_state;
0237     int i;
0238     bool fence_cookie = dma_fence_begin_signalling();
0239 
0240     pm_runtime_get_sync(drm->dev);
0241 
0242     /*
0243      * set config_valid to a special value to let IRQ handlers
0244      * know that we are updating registers
0245      */
0246     atomic_set(&malidp->config_valid, MALIDP_CONFIG_START);
0247     malidp->dev->hw->set_config_valid(malidp->dev, 0);
0248 
0249     drm_atomic_helper_commit_modeset_disables(drm, state);
0250 
0251     for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
0252         malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
0253         malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
0254         malidp_atomic_commit_se_config(crtc, old_crtc_state);
0255     }
0256 
0257     drm_atomic_helper_commit_planes(drm, state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
0258 
0259     malidp_mw_atomic_commit(drm, state);
0260 
0261     drm_atomic_helper_commit_modeset_enables(drm, state);
0262 
0263     malidp_atomic_commit_hw_done(state);
0264 
0265     dma_fence_end_signalling(fence_cookie);
0266 
0267     pm_runtime_put(drm->dev);
0268 
0269     drm_atomic_helper_cleanup_planes(drm, state);
0270 }
0271 
0272 static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = {
0273     .atomic_commit_tail = malidp_atomic_commit_tail,
0274 };
0275 
0276 static bool
0277 malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
0278                     const struct drm_mode_fb_cmd2 *mode_cmd)
0279 {
0280     if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
0281                     mode_cmd->modifier[0]) == false)
0282         return false;
0283 
0284     if (mode_cmd->offsets[0] != 0) {
0285         DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
0286         return false;
0287     }
0288 
0289     switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
0290     case AFBC_SIZE_16X16:
0291         if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
0292             DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 pixels\n");
0293             return false;
0294         }
0295         break;
0296     default:
0297         DRM_DEBUG_KMS("Unsupported AFBC block size\n");
0298         return false;
0299     }
0300 
0301     return true;
0302 }
0303 
0304 static bool
0305 malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
0306                     struct drm_file *file,
0307                     const struct drm_mode_fb_cmd2 *mode_cmd)
0308 {
0309     int n_superblocks = 0;
0310     const struct drm_format_info *info;
0311     struct drm_gem_object *objs = NULL;
0312     u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
0313     u32 afbc_superblock_width = 0, afbc_size = 0;
0314     int bpp = 0;
0315 
0316     switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
0317     case AFBC_SIZE_16X16:
0318         afbc_superblock_height = 16;
0319         afbc_superblock_width = 16;
0320         break;
0321     default:
0322         DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
0323         return false;
0324     }
0325 
0326     info = drm_get_format_info(dev, mode_cmd);
0327 
0328     n_superblocks = (mode_cmd->width / afbc_superblock_width) *
0329         (mode_cmd->height / afbc_superblock_height);
0330 
0331     bpp = malidp_format_get_bpp(info->format);
0332 
0333     afbc_superblock_size = (bpp * afbc_superblock_width * afbc_superblock_height)
0334                 / BITS_PER_BYTE;
0335 
0336     afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE, AFBC_SUPERBLK_ALIGNMENT);
0337     afbc_size += n_superblocks * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
0338 
0339     if ((mode_cmd->width * bpp) != (mode_cmd->pitches[0] * BITS_PER_BYTE)) {
0340         DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) (=%u) "
0341                   "should be same as width (=%u) * bpp (=%u)\n",
0342                   (mode_cmd->pitches[0] * BITS_PER_BYTE),
0343                   mode_cmd->width, bpp);
0344         return false;
0345     }
0346 
0347     objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
0348     if (!objs) {
0349         DRM_DEBUG_KMS("Failed to lookup GEM object\n");
0350         return false;
0351     }
0352 
0353     if (objs->size < afbc_size) {
0354         DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC buffer size = %u\n",
0355                   objs->size, afbc_size);
0356         drm_gem_object_put(objs);
0357         return false;
0358     }
0359 
0360     drm_gem_object_put(objs);
0361 
0362     return true;
0363 }
0364 
0365 static bool
0366 malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
0367                    const struct drm_mode_fb_cmd2 *mode_cmd)
0368 {
0369     if (malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
0370         return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
0371 
0372     return false;
0373 }
0374 
0375 static struct drm_framebuffer *
0376 malidp_fb_create(struct drm_device *dev, struct drm_file *file,
0377          const struct drm_mode_fb_cmd2 *mode_cmd)
0378 {
0379     if (mode_cmd->modifier[0]) {
0380         if (!malidp_verify_afbc_framebuffer(dev, file, mode_cmd))
0381             return ERR_PTR(-EINVAL);
0382     }
0383 
0384     return drm_gem_fb_create(dev, file, mode_cmd);
0385 }
0386 
0387 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
0388     .fb_create = malidp_fb_create,
0389     .atomic_check = drm_atomic_helper_check,
0390     .atomic_commit = drm_atomic_helper_commit,
0391 };
0392 
0393 static int malidp_init(struct drm_device *drm)
0394 {
0395     int ret;
0396     struct malidp_drm *malidp = drm->dev_private;
0397     struct malidp_hw_device *hwdev = malidp->dev;
0398 
0399     drm_mode_config_init(drm);
0400 
0401     drm->mode_config.min_width = hwdev->min_line_size;
0402     drm->mode_config.min_height = hwdev->min_line_size;
0403     drm->mode_config.max_width = hwdev->max_line_size;
0404     drm->mode_config.max_height = hwdev->max_line_size;
0405     drm->mode_config.funcs = &malidp_mode_config_funcs;
0406     drm->mode_config.helper_private = &malidp_mode_config_helpers;
0407 
0408     ret = malidp_crtc_init(drm);
0409     if (ret)
0410         goto crtc_fail;
0411 
0412     ret = malidp_mw_connector_init(drm);
0413     if (ret)
0414         goto crtc_fail;
0415 
0416     return 0;
0417 
0418 crtc_fail:
0419     drm_mode_config_cleanup(drm);
0420     return ret;
0421 }
0422 
0423 static void malidp_fini(struct drm_device *drm)
0424 {
0425     drm_mode_config_cleanup(drm);
0426 }
0427 
0428 static int malidp_irq_init(struct platform_device *pdev)
0429 {
0430     int irq_de, irq_se, ret = 0;
0431     struct drm_device *drm = dev_get_drvdata(&pdev->dev);
0432     struct malidp_drm *malidp = drm->dev_private;
0433     struct malidp_hw_device *hwdev = malidp->dev;
0434 
0435     /* fetch the interrupts from DT */
0436     irq_de = platform_get_irq_byname(pdev, "DE");
0437     if (irq_de < 0) {
0438         DRM_ERROR("no 'DE' IRQ specified!\n");
0439         return irq_de;
0440     }
0441     irq_se = platform_get_irq_byname(pdev, "SE");
0442     if (irq_se < 0) {
0443         DRM_ERROR("no 'SE' IRQ specified!\n");
0444         return irq_se;
0445     }
0446 
0447     ret = malidp_de_irq_init(drm, irq_de);
0448     if (ret)
0449         return ret;
0450 
0451     ret = malidp_se_irq_init(drm, irq_se);
0452     if (ret) {
0453         malidp_de_irq_fini(hwdev);
0454         return ret;
0455     }
0456 
0457     return 0;
0458 }
0459 
0460 DEFINE_DRM_GEM_CMA_FOPS(fops);
0461 
0462 static int malidp_dumb_create(struct drm_file *file_priv,
0463                   struct drm_device *drm,
0464                   struct drm_mode_create_dumb *args)
0465 {
0466     struct malidp_drm *malidp = drm->dev_private;
0467     /* allocate for the worst case scenario, i.e. rotated buffers */
0468     u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1);
0469 
0470     args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), alignment);
0471 
0472     return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
0473 }
0474 
0475 #ifdef CONFIG_DEBUG_FS
0476 
0477 static void malidp_error_stats_init(struct malidp_error_stats *error_stats)
0478 {
0479     error_stats->num_errors = 0;
0480     error_stats->last_error_status = 0;
0481     error_stats->last_error_vblank = -1;
0482 }
0483 
0484 void malidp_error(struct malidp_drm *malidp,
0485           struct malidp_error_stats *error_stats, u32 status,
0486           u64 vblank)
0487 {
0488     unsigned long irqflags;
0489 
0490     spin_lock_irqsave(&malidp->errors_lock, irqflags);
0491     error_stats->last_error_status = status;
0492     error_stats->last_error_vblank = vblank;
0493     error_stats->num_errors++;
0494     spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
0495 }
0496 
0497 static void malidp_error_stats_dump(const char *prefix,
0498                     struct malidp_error_stats error_stats,
0499                     struct seq_file *m)
0500 {
0501     seq_printf(m, "[%s] num_errors : %d\n", prefix,
0502            error_stats.num_errors);
0503     seq_printf(m, "[%s] last_error_status  : 0x%08x\n", prefix,
0504            error_stats.last_error_status);
0505     seq_printf(m, "[%s] last_error_vblank : %lld\n", prefix,
0506            error_stats.last_error_vblank);
0507 }
0508 
0509 static int malidp_show_stats(struct seq_file *m, void *arg)
0510 {
0511     struct drm_device *drm = m->private;
0512     struct malidp_drm *malidp = drm->dev_private;
0513     unsigned long irqflags;
0514     struct malidp_error_stats de_errors, se_errors;
0515 
0516     spin_lock_irqsave(&malidp->errors_lock, irqflags);
0517     de_errors = malidp->de_errors;
0518     se_errors = malidp->se_errors;
0519     spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
0520     malidp_error_stats_dump("DE", de_errors, m);
0521     malidp_error_stats_dump("SE", se_errors, m);
0522     return 0;
0523 }
0524 
0525 static int malidp_debugfs_open(struct inode *inode, struct file *file)
0526 {
0527     return single_open(file, malidp_show_stats, inode->i_private);
0528 }
0529 
0530 static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
0531                     size_t len, loff_t *offp)
0532 {
0533     struct seq_file *m = file->private_data;
0534     struct drm_device *drm = m->private;
0535     struct malidp_drm *malidp = drm->dev_private;
0536     unsigned long irqflags;
0537 
0538     spin_lock_irqsave(&malidp->errors_lock, irqflags);
0539     malidp_error_stats_init(&malidp->de_errors);
0540     malidp_error_stats_init(&malidp->se_errors);
0541     spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
0542     return len;
0543 }
0544 
0545 static const struct file_operations malidp_debugfs_fops = {
0546     .owner = THIS_MODULE,
0547     .open = malidp_debugfs_open,
0548     .read = seq_read,
0549     .write = malidp_debugfs_write,
0550     .llseek = seq_lseek,
0551     .release = single_release,
0552 };
0553 
0554 static void malidp_debugfs_init(struct drm_minor *minor)
0555 {
0556     struct malidp_drm *malidp = minor->dev->dev_private;
0557 
0558     malidp_error_stats_init(&malidp->de_errors);
0559     malidp_error_stats_init(&malidp->se_errors);
0560     spin_lock_init(&malidp->errors_lock);
0561     debugfs_create_file("debug", S_IRUGO | S_IWUSR, minor->debugfs_root,
0562                 minor->dev, &malidp_debugfs_fops);
0563 }
0564 
0565 #endif //CONFIG_DEBUG_FS
0566 
0567 static const struct drm_driver malidp_driver = {
0568     .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
0569     DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(malidp_dumb_create),
0570 #ifdef CONFIG_DEBUG_FS
0571     .debugfs_init = malidp_debugfs_init,
0572 #endif
0573     .fops = &fops,
0574     .name = "mali-dp",
0575     .desc = "ARM Mali Display Processor driver",
0576     .date = "20160106",
0577     .major = 1,
0578     .minor = 0,
0579 };
0580 
0581 static const struct of_device_id  malidp_drm_of_match[] = {
0582     {
0583         .compatible = "arm,mali-dp500",
0584         .data = &malidp_device[MALIDP_500]
0585     },
0586     {
0587         .compatible = "arm,mali-dp550",
0588         .data = &malidp_device[MALIDP_550]
0589     },
0590     {
0591         .compatible = "arm,mali-dp650",
0592         .data = &malidp_device[MALIDP_650]
0593     },
0594     {},
0595 };
0596 MODULE_DEVICE_TABLE(of, malidp_drm_of_match);
0597 
0598 static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev,
0599                        const struct of_device_id *dev_id)
0600 {
0601     u32 core_id;
0602     const char *compatstr_dp500 = "arm,mali-dp500";
0603     bool is_dp500;
0604     bool dt_is_dp500;
0605 
0606     /*
0607      * The DP500 CORE_ID register is in a different location, so check it
0608      * first. If the product id field matches, then this is DP500, otherwise
0609      * check the DP550/650 CORE_ID register.
0610      */
0611     core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID);
0612     /* Offset 0x18 will never read 0x500 on products other than DP500. */
0613     is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500);
0614     dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500,
0615                   sizeof(dev_id->compatible)) != NULL;
0616     if (is_dp500 != dt_is_dp500) {
0617         DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n",
0618               dev_id->compatible, is_dp500 ? "is" : "is not");
0619         return false;
0620     } else if (!dt_is_dp500) {
0621         u16 product_id;
0622         char buf[32];
0623 
0624         core_id = malidp_hw_read(hwdev,
0625                      MALIDP550_DC_BASE + MALIDP_DE_CORE_ID);
0626         product_id = MALIDP_PRODUCT_ID(core_id);
0627         snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id);
0628         if (!strnstr(dev_id->compatible, buf,
0629                  sizeof(dev_id->compatible))) {
0630             DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n",
0631                   dev_id->compatible, product_id);
0632             return false;
0633         }
0634     }
0635     return true;
0636 }
0637 
0638 static bool malidp_has_sufficient_address_space(const struct resource *res,
0639                         const struct of_device_id *dev_id)
0640 {
0641     resource_size_t res_size = resource_size(res);
0642     const char *compatstr_dp500 = "arm,mali-dp500";
0643 
0644     if (!strnstr(dev_id->compatible, compatstr_dp500,
0645              sizeof(dev_id->compatible)))
0646         return res_size >= MALIDP550_ADDR_SPACE_SIZE;
0647     else if (res_size < MALIDP500_ADDR_SPACE_SIZE)
0648         return false;
0649     return true;
0650 }
0651 
0652 static ssize_t core_id_show(struct device *dev, struct device_attribute *attr,
0653                 char *buf)
0654 {
0655     struct drm_device *drm = dev_get_drvdata(dev);
0656     struct malidp_drm *malidp = drm->dev_private;
0657 
0658     return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
0659 }
0660 
0661 static DEVICE_ATTR_RO(core_id);
0662 
0663 static struct attribute *mali_dp_attrs[] = {
0664     &dev_attr_core_id.attr,
0665     NULL,
0666 };
0667 ATTRIBUTE_GROUPS(mali_dp);
0668 
0669 #define MAX_OUTPUT_CHANNELS 3
0670 
0671 static int malidp_runtime_pm_suspend(struct device *dev)
0672 {
0673     struct drm_device *drm = dev_get_drvdata(dev);
0674     struct malidp_drm *malidp = drm->dev_private;
0675     struct malidp_hw_device *hwdev = malidp->dev;
0676 
0677     /* we can only suspend if the hardware is in config mode */
0678     WARN_ON(!hwdev->hw->in_config_mode(hwdev));
0679 
0680     malidp_se_irq_fini(hwdev);
0681     malidp_de_irq_fini(hwdev);
0682     hwdev->pm_suspended = true;
0683     clk_disable_unprepare(hwdev->mclk);
0684     clk_disable_unprepare(hwdev->aclk);
0685     clk_disable_unprepare(hwdev->pclk);
0686 
0687     return 0;
0688 }
0689 
0690 static int malidp_runtime_pm_resume(struct device *dev)
0691 {
0692     struct drm_device *drm = dev_get_drvdata(dev);
0693     struct malidp_drm *malidp = drm->dev_private;
0694     struct malidp_hw_device *hwdev = malidp->dev;
0695 
0696     clk_prepare_enable(hwdev->pclk);
0697     clk_prepare_enable(hwdev->aclk);
0698     clk_prepare_enable(hwdev->mclk);
0699     hwdev->pm_suspended = false;
0700     malidp_de_irq_hw_init(hwdev);
0701     malidp_se_irq_hw_init(hwdev);
0702 
0703     return 0;
0704 }
0705 
0706 static int malidp_bind(struct device *dev)
0707 {
0708     struct resource *res;
0709     struct drm_device *drm;
0710     struct malidp_drm *malidp;
0711     struct malidp_hw_device *hwdev;
0712     struct platform_device *pdev = to_platform_device(dev);
0713     struct of_device_id const *dev_id;
0714     struct drm_encoder *encoder;
0715     /* number of lines for the R, G and B output */
0716     u8 output_width[MAX_OUTPUT_CHANNELS];
0717     int ret = 0, i;
0718     u32 version, out_depth = 0;
0719 
0720     malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL);
0721     if (!malidp)
0722         return -ENOMEM;
0723 
0724     hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL);
0725     if (!hwdev)
0726         return -ENOMEM;
0727 
0728     hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
0729     malidp->dev = hwdev;
0730 
0731     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0732     hwdev->regs = devm_ioremap_resource(dev, res);
0733     if (IS_ERR(hwdev->regs))
0734         return PTR_ERR(hwdev->regs);
0735 
0736     hwdev->pclk = devm_clk_get(dev, "pclk");
0737     if (IS_ERR(hwdev->pclk))
0738         return PTR_ERR(hwdev->pclk);
0739 
0740     hwdev->aclk = devm_clk_get(dev, "aclk");
0741     if (IS_ERR(hwdev->aclk))
0742         return PTR_ERR(hwdev->aclk);
0743 
0744     hwdev->mclk = devm_clk_get(dev, "mclk");
0745     if (IS_ERR(hwdev->mclk))
0746         return PTR_ERR(hwdev->mclk);
0747 
0748     hwdev->pxlclk = devm_clk_get(dev, "pxlclk");
0749     if (IS_ERR(hwdev->pxlclk))
0750         return PTR_ERR(hwdev->pxlclk);
0751 
0752     /* Get the optional framebuffer memory resource */
0753     ret = of_reserved_mem_device_init(dev);
0754     if (ret && ret != -ENODEV)
0755         return ret;
0756 
0757     drm = drm_dev_alloc(&malidp_driver, dev);
0758     if (IS_ERR(drm)) {
0759         ret = PTR_ERR(drm);
0760         goto alloc_fail;
0761     }
0762 
0763     drm->dev_private = malidp;
0764     dev_set_drvdata(dev, drm);
0765 
0766     /* Enable power management */
0767     pm_runtime_enable(dev);
0768 
0769     /* Resume device to enable the clocks */
0770     if (pm_runtime_enabled(dev))
0771         pm_runtime_get_sync(dev);
0772     else
0773         malidp_runtime_pm_resume(dev);
0774 
0775     dev_id = of_match_device(malidp_drm_of_match, dev);
0776     if (!dev_id) {
0777         ret = -EINVAL;
0778         goto query_hw_fail;
0779     }
0780 
0781     if (!malidp_has_sufficient_address_space(res, dev_id)) {
0782         DRM_ERROR("Insufficient address space in device-tree.\n");
0783         ret = -EINVAL;
0784         goto query_hw_fail;
0785     }
0786 
0787     if (!malidp_is_compatible_hw_id(hwdev, dev_id)) {
0788         ret = -EINVAL;
0789         goto query_hw_fail;
0790     }
0791 
0792     ret = hwdev->hw->query_hw(hwdev);
0793     if (ret) {
0794         DRM_ERROR("Invalid HW configuration\n");
0795         goto query_hw_fail;
0796     }
0797 
0798     version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID);
0799     DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16,
0800          (version >> 12) & 0xf, (version >> 8) & 0xf);
0801 
0802     malidp->core_id = version;
0803 
0804     ret = of_property_read_u32(dev->of_node,
0805                     "arm,malidp-arqos-value",
0806                     &hwdev->arqos_value);
0807     if (ret)
0808         hwdev->arqos_value = 0x0;
0809 
0810     /* set the number of lines used for output of RGB data */
0811     ret = of_property_read_u8_array(dev->of_node,
0812                     "arm,malidp-output-port-lines",
0813                     output_width, MAX_OUTPUT_CHANNELS);
0814     if (ret)
0815         goto query_hw_fail;
0816 
0817     for (i = 0; i < MAX_OUTPUT_CHANNELS; i++)
0818         out_depth = (out_depth << 8) | (output_width[i] & 0xf);
0819     malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base);
0820     hwdev->output_color_depth = out_depth;
0821 
0822     atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_INIT);
0823     init_waitqueue_head(&malidp->wq);
0824 
0825     ret = malidp_init(drm);
0826     if (ret < 0)
0827         goto query_hw_fail;
0828 
0829     /* Set the CRTC's port so that the encoder component can find it */
0830     malidp->crtc.port = of_graph_get_port_by_id(dev->of_node, 0);
0831 
0832     ret = component_bind_all(dev, drm);
0833     if (ret) {
0834         DRM_ERROR("Failed to bind all components\n");
0835         goto bind_fail;
0836     }
0837 
0838     /* We expect to have a maximum of two encoders one for the actual
0839      * display and a virtual one for the writeback connector
0840      */
0841     WARN_ON(drm->mode_config.num_encoder > 2);
0842     list_for_each_entry(encoder, &drm->mode_config.encoder_list, head) {
0843         encoder->possible_clones =
0844                 (1 << drm->mode_config.num_encoder) -  1;
0845     }
0846 
0847     ret = malidp_irq_init(pdev);
0848     if (ret < 0)
0849         goto irq_init_fail;
0850 
0851     ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
0852     if (ret < 0) {
0853         DRM_ERROR("failed to initialise vblank\n");
0854         goto vblank_fail;
0855     }
0856     pm_runtime_put(dev);
0857 
0858     drm_mode_config_reset(drm);
0859 
0860     drm_kms_helper_poll_init(drm);
0861 
0862     ret = drm_dev_register(drm, 0);
0863     if (ret)
0864         goto register_fail;
0865 
0866     drm_fbdev_generic_setup(drm, 32);
0867 
0868     return 0;
0869 
0870 register_fail:
0871     drm_kms_helper_poll_fini(drm);
0872     pm_runtime_get_sync(dev);
0873 vblank_fail:
0874     malidp_se_irq_fini(hwdev);
0875     malidp_de_irq_fini(hwdev);
0876 irq_init_fail:
0877     drm_atomic_helper_shutdown(drm);
0878     component_unbind_all(dev, drm);
0879 bind_fail:
0880     of_node_put(malidp->crtc.port);
0881     malidp->crtc.port = NULL;
0882     malidp_fini(drm);
0883 query_hw_fail:
0884     pm_runtime_put(dev);
0885     if (pm_runtime_enabled(dev))
0886         pm_runtime_disable(dev);
0887     else
0888         malidp_runtime_pm_suspend(dev);
0889     drm->dev_private = NULL;
0890     dev_set_drvdata(dev, NULL);
0891     drm_dev_put(drm);
0892 alloc_fail:
0893     of_reserved_mem_device_release(dev);
0894 
0895     return ret;
0896 }
0897 
0898 static void malidp_unbind(struct device *dev)
0899 {
0900     struct drm_device *drm = dev_get_drvdata(dev);
0901     struct malidp_drm *malidp = drm->dev_private;
0902     struct malidp_hw_device *hwdev = malidp->dev;
0903 
0904     drm_dev_unregister(drm);
0905     drm_kms_helper_poll_fini(drm);
0906     pm_runtime_get_sync(dev);
0907     drm_atomic_helper_shutdown(drm);
0908     malidp_se_irq_fini(hwdev);
0909     malidp_de_irq_fini(hwdev);
0910     component_unbind_all(dev, drm);
0911     of_node_put(malidp->crtc.port);
0912     malidp->crtc.port = NULL;
0913     malidp_fini(drm);
0914     pm_runtime_put(dev);
0915     if (pm_runtime_enabled(dev))
0916         pm_runtime_disable(dev);
0917     else
0918         malidp_runtime_pm_suspend(dev);
0919     drm->dev_private = NULL;
0920     dev_set_drvdata(dev, NULL);
0921     drm_dev_put(drm);
0922     of_reserved_mem_device_release(dev);
0923 }
0924 
0925 static const struct component_master_ops malidp_master_ops = {
0926     .bind = malidp_bind,
0927     .unbind = malidp_unbind,
0928 };
0929 
0930 static int malidp_compare_dev(struct device *dev, void *data)
0931 {
0932     struct device_node *np = data;
0933 
0934     return dev->of_node == np;
0935 }
0936 
0937 static int malidp_platform_probe(struct platform_device *pdev)
0938 {
0939     struct device_node *port;
0940     struct component_match *match = NULL;
0941 
0942     if (!pdev->dev.of_node)
0943         return -ENODEV;
0944 
0945     /* there is only one output port inside each device, find it */
0946     port = of_graph_get_remote_node(pdev->dev.of_node, 0, 0);
0947     if (!port)
0948         return -ENODEV;
0949 
0950     drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev,
0951                    port);
0952     of_node_put(port);
0953     return component_master_add_with_match(&pdev->dev, &malidp_master_ops,
0954                            match);
0955 }
0956 
0957 static int malidp_platform_remove(struct platform_device *pdev)
0958 {
0959     component_master_del(&pdev->dev, &malidp_master_ops);
0960     return 0;
0961 }
0962 
0963 static int __maybe_unused malidp_pm_suspend(struct device *dev)
0964 {
0965     struct drm_device *drm = dev_get_drvdata(dev);
0966 
0967     return drm_mode_config_helper_suspend(drm);
0968 }
0969 
0970 static int __maybe_unused malidp_pm_resume(struct device *dev)
0971 {
0972     struct drm_device *drm = dev_get_drvdata(dev);
0973 
0974     drm_mode_config_helper_resume(drm);
0975 
0976     return 0;
0977 }
0978 
0979 static int __maybe_unused malidp_pm_suspend_late(struct device *dev)
0980 {
0981     if (!pm_runtime_status_suspended(dev)) {
0982         malidp_runtime_pm_suspend(dev);
0983         pm_runtime_set_suspended(dev);
0984     }
0985     return 0;
0986 }
0987 
0988 static int __maybe_unused malidp_pm_resume_early(struct device *dev)
0989 {
0990     malidp_runtime_pm_resume(dev);
0991     pm_runtime_set_active(dev);
0992     return 0;
0993 }
0994 
0995 static const struct dev_pm_ops malidp_pm_ops = {
0996     SET_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend, malidp_pm_resume) \
0997     SET_LATE_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend_late, malidp_pm_resume_early) \
0998     SET_RUNTIME_PM_OPS(malidp_runtime_pm_suspend, malidp_runtime_pm_resume, NULL)
0999 };
1000 
1001 static struct platform_driver malidp_platform_driver = {
1002     .probe      = malidp_platform_probe,
1003     .remove     = malidp_platform_remove,
1004     .driver = {
1005         .name = "mali-dp",
1006         .pm = &malidp_pm_ops,
1007         .of_match_table = malidp_drm_of_match,
1008         .dev_groups = mali_dp_groups,
1009     },
1010 };
1011 
1012 drm_module_platform_driver(malidp_platform_driver);
1013 
1014 MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
1015 MODULE_DESCRIPTION("ARM Mali DP DRM driver");
1016 MODULE_LICENSE("GPL v2");