cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

msm_drv.h (15752B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
      4 * Copyright (C) 2013 Red Hat
      5 * Author: Rob Clark <robdclark@gmail.com>
      6 */
      7
      8#ifndef __MSM_DRV_H__
      9#define __MSM_DRV_H__
     10
     11#include <linux/kernel.h>
     12#include <linux/clk.h>
     13#include <linux/cpufreq.h>
     14#include <linux/module.h>
     15#include <linux/component.h>
     16#include <linux/platform_device.h>
     17#include <linux/pm.h>
     18#include <linux/pm_runtime.h>
     19#include <linux/slab.h>
     20#include <linux/list.h>
     21#include <linux/iommu.h>
     22#include <linux/types.h>
     23#include <linux/of_graph.h>
     24#include <linux/of_device.h>
     25#include <linux/sizes.h>
     26#include <linux/kthread.h>
     27
     28#include <drm/drm_atomic.h>
     29#include <drm/drm_atomic_helper.h>
     30#include <drm/drm_plane_helper.h>
     31#include <drm/drm_probe_helper.h>
     32#include <drm/drm_fb_helper.h>
     33#include <drm/display/drm_dsc.h>
     34#include <drm/msm_drm.h>
     35#include <drm/drm_gem.h>
     36
     37struct msm_kms;
     38struct msm_gpu;
     39struct msm_mmu;
     40struct msm_mdss;
     41struct msm_rd_state;
     42struct msm_perf_state;
     43struct msm_gem_submit;
     44struct msm_fence_context;
     45struct msm_gem_address_space;
     46struct msm_gem_vma;
     47struct msm_disp_state;
     48
     49#define MAX_CRTCS      8
     50#define MAX_BRIDGES    8
     51
     52#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
     53
     54enum msm_dp_controller {
     55	MSM_DP_CONTROLLER_0,
     56	MSM_DP_CONTROLLER_1,
     57	MSM_DP_CONTROLLER_2,
     58	MSM_DP_CONTROLLER_COUNT,
     59};
     60
     61#define MSM_GPU_MAX_RINGS 4
     62#define MAX_H_TILES_PER_DISPLAY 2
     63
     64/**
     65 * enum msm_display_caps - features/capabilities supported by displays
     66 * @MSM_DISPLAY_CAP_VID_MODE:           Video or "active" mode supported
     67 * @MSM_DISPLAY_CAP_CMD_MODE:           Command mode supported
     68 */
     69enum msm_display_caps {
     70	MSM_DISPLAY_CAP_VID_MODE	= BIT(0),
     71	MSM_DISPLAY_CAP_CMD_MODE	= BIT(1),
     72};
     73
     74/**
     75 * enum msm_event_wait - type of HW events to wait for
     76 * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
     77 * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel
     78 * @MSM_ENC_VBLANK - wait for the HW VBLANK event (for driver-internal waiters)
     79 */
     80enum msm_event_wait {
     81	MSM_ENC_COMMIT_DONE = 0,
     82	MSM_ENC_TX_COMPLETE,
     83	MSM_ENC_VBLANK,
     84};
     85
     86/**
     87 * struct msm_display_topology - defines a display topology pipeline
     88 * @num_lm:       number of layer mixers used
     89 * @num_enc:      number of compression encoder blocks used
     90 * @num_intf:     number of interfaces the panel is mounted on
     91 * @num_dspp:     number of dspp blocks used
     92 * @num_dsc:      number of Display Stream Compression (DSC) blocks used
     93 */
     94struct msm_display_topology {
     95	u32 num_lm;
     96	u32 num_enc;
     97	u32 num_intf;
     98	u32 num_dspp;
     99	u32 num_dsc;
    100};
    101
    102/* Commit/Event thread specific structure */
    103struct msm_drm_thread {
    104	struct drm_device *dev;
    105	unsigned int crtc_id;
    106	struct kthread_worker *worker;
    107};
    108
    109/* DSC config */
    110struct msm_display_dsc_config {
    111	struct drm_dsc_config *drm;
    112};
    113
    114struct msm_drm_private {
    115
    116	struct drm_device *dev;
    117
    118	struct msm_kms *kms;
    119	int (*kms_init)(struct drm_device *dev);
    120
    121	/* subordinate devices, if present: */
    122	struct platform_device *gpu_pdev;
    123
    124	/* possibly this should be in the kms component, but it is
    125	 * shared by both mdp4 and mdp5..
    126	 */
    127	struct hdmi *hdmi;
    128
    129	/* DSI is shared by mdp4 and mdp5 */
    130	struct msm_dsi *dsi[2];
    131
    132	struct msm_dp *dp[MSM_DP_CONTROLLER_COUNT];
    133
    134	/* when we have more than one 'msm_gpu' these need to be an array: */
    135	struct msm_gpu *gpu;
    136
    137	/* gpu is only set on open(), but we need this info earlier */
    138	bool is_a2xx;
    139	bool has_cached_coherent;
    140
    141	struct drm_fb_helper *fbdev;
    142
    143	struct msm_rd_state *rd;       /* debugfs to dump all submits */
    144	struct msm_rd_state *hangrd;   /* debugfs to dump hanging submits */
    145	struct msm_perf_state *perf;
    146
    147	/**
    148	 * List of all GEM objects (mainly for debugfs, protected by obj_lock
    149	 * (acquire before per GEM object lock)
    150	 */
    151	struct list_head objects;
    152	struct mutex obj_lock;
    153
    154	/**
    155	 * LRUs of inactive GEM objects.  Every bo is either in one of the
    156	 * inactive lists (depending on whether or not it is shrinkable) or
    157	 * gpu->active_list (for the gpu it is active on[1]), or transiently
    158	 * on a temporary list as the shrinker is running.
    159	 *
    160	 * Note that inactive_willneed also contains pinned and vmap'd bos,
    161	 * but the number of pinned-but-not-active objects is small (scanout
    162	 * buffers, ringbuffer, etc).
    163	 *
    164	 * These lists are protected by mm_lock (which should be acquired
    165	 * before per GEM object lock).  One should *not* hold mm_lock in
    166	 * get_pages()/vmap()/etc paths, as they can trigger the shrinker.
    167	 *
    168	 * [1] if someone ever added support for the old 2d cores, there could be
    169	 *     more than one gpu object
    170	 */
    171	struct list_head inactive_willneed;  /* inactive + potentially unpin/evictable */
    172	struct list_head inactive_dontneed;  /* inactive + shrinkable */
    173	struct list_head inactive_unpinned;  /* inactive + purged or unpinned */
    174	long shrinkable_count;               /* write access under mm_lock */
    175	long evictable_count;                /* write access under mm_lock */
    176	struct mutex mm_lock;
    177
    178	struct workqueue_struct *wq;
    179
    180	unsigned int num_crtcs;
    181	struct drm_crtc *crtcs[MAX_CRTCS];
    182
    183	struct msm_drm_thread event_thread[MAX_CRTCS];
    184
    185	unsigned int num_bridges;
    186	struct drm_bridge *bridges[MAX_BRIDGES];
    187
    188	/* VRAM carveout, used when no IOMMU: */
    189	struct {
    190		unsigned long size;
    191		dma_addr_t paddr;
    192		/* NOTE: mm managed at the page level, size is in # of pages
    193		 * and position mm_node->start is in # of pages:
    194		 */
    195		struct drm_mm mm;
    196		spinlock_t lock; /* Protects drm_mm node allocation/removal */
    197	} vram;
    198
    199	struct notifier_block vmap_notifier;
    200	struct shrinker shrinker;
    201
    202	struct drm_atomic_state *pm_state;
    203
    204	/* For hang detection, in ms */
    205	unsigned int hangcheck_period;
    206
    207	/**
    208	 * disable_err_irq:
    209	 *
    210	 * Disable handling of GPU hw error interrupts, to force fallback to
    211	 * sw hangcheck timer.  Written (via debugfs) by igt tests to test
    212	 * the sw hangcheck mechanism.
    213	 */
    214	bool disable_err_irq;
    215};
    216
    217struct msm_format {
    218	uint32_t pixel_format;
    219};
    220
    221struct msm_pending_timer;
    222
    223int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
    224		struct msm_kms *kms, int crtc_idx);
    225void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
    226void msm_atomic_commit_tail(struct drm_atomic_state *state);
    227struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
    228void msm_atomic_state_clear(struct drm_atomic_state *state);
    229void msm_atomic_state_free(struct drm_atomic_state *state);
    230
    231int msm_crtc_enable_vblank(struct drm_crtc *crtc);
    232void msm_crtc_disable_vblank(struct drm_crtc *crtc);
    233
    234int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
    235void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
    236
    237bool msm_use_mmu(struct drm_device *dev);
    238
    239int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
    240		struct drm_file *file);
    241
    242#ifdef CONFIG_DEBUG_FS
    243unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_to_scan);
    244#endif
    245
    246void msm_gem_shrinker_init(struct drm_device *dev);
    247void msm_gem_shrinker_cleanup(struct drm_device *dev);
    248
    249int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
    250struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
    251int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
    252void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
    253struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
    254		struct dma_buf_attachment *attach, struct sg_table *sg);
    255int msm_gem_prime_pin(struct drm_gem_object *obj);
    256void msm_gem_prime_unpin(struct drm_gem_object *obj);
    257
    258int msm_framebuffer_prepare(struct drm_framebuffer *fb,
    259		struct msm_gem_address_space *aspace, bool needs_dirtyfb);
    260void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
    261		struct msm_gem_address_space *aspace, bool needed_dirtyfb);
    262uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
    263		struct msm_gem_address_space *aspace, int plane);
    264struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
    265const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
    266struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
    267		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
    268struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
    269		int w, int h, int p, uint32_t format);
    270
    271struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
    272void msm_fbdev_free(struct drm_device *dev);
    273
    274struct hdmi;
    275#ifdef CONFIG_DRM_MSM_HDMI
    276int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
    277		struct drm_encoder *encoder);
    278void __init msm_hdmi_register(void);
    279void __exit msm_hdmi_unregister(void);
    280#else
    281static inline int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
    282		struct drm_encoder *encoder)
    283{
    284	return -EINVAL;
    285}
    286static inline void __init msm_hdmi_register(void) {}
    287static inline void __exit msm_hdmi_unregister(void) {}
    288#endif
    289
    290struct msm_dsi;
    291#ifdef CONFIG_DRM_MSM_DSI
    292int dsi_dev_attach(struct platform_device *pdev);
    293void dsi_dev_detach(struct platform_device *pdev);
    294void __init msm_dsi_register(void);
    295void __exit msm_dsi_unregister(void);
    296int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
    297			 struct drm_encoder *encoder);
    298void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi);
    299bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
    300bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
    301bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi);
    302struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
    303#else
    304static inline void __init msm_dsi_register(void)
    305{
    306}
    307static inline void __exit msm_dsi_unregister(void)
    308{
    309}
    310static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
    311				       struct drm_device *dev,
    312				       struct drm_encoder *encoder)
    313{
    314	return -EINVAL;
    315}
    316static inline void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi)
    317{
    318}
    319static inline bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
    320{
    321	return false;
    322}
    323static inline bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
    324{
    325	return false;
    326}
    327static inline bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
    328{
    329	return false;
    330}
    331
    332static inline struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
    333{
    334	return NULL;
    335}
    336#endif
    337
    338#ifdef CONFIG_DRM_MSM_DP
    339int __init msm_dp_register(void);
    340void __exit msm_dp_unregister(void);
    341int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
    342			 struct drm_encoder *encoder);
    343void msm_dp_irq_postinstall(struct msm_dp *dp_display);
    344void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
    345
    346void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
    347bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
    348
    349#else
    350static inline int __init msm_dp_register(void)
    351{
    352	return -EINVAL;
    353}
    354static inline void __exit msm_dp_unregister(void)
    355{
    356}
    357static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
    358				       struct drm_device *dev,
    359				       struct drm_encoder *encoder)
    360{
    361	return -EINVAL;
    362}
    363
    364static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
    365{
    366}
    367
    368static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display)
    369{
    370}
    371
    372static inline void msm_dp_debugfs_init(struct msm_dp *dp_display,
    373		struct drm_minor *minor)
    374{
    375}
    376
    377static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
    378{
    379	return false;
    380}
    381
    382#endif
    383
    384#ifdef CONFIG_DRM_MSM_MDP4
    385void msm_mdp4_register(void);
    386void msm_mdp4_unregister(void);
    387#else
    388static inline void msm_mdp4_register(void) {}
    389static inline void msm_mdp4_unregister(void) {}
    390#endif
    391
    392#ifdef CONFIG_DRM_MSM_MDP5
    393void msm_mdp_register(void);
    394void msm_mdp_unregister(void);
    395#else
    396static inline void msm_mdp_register(void) {}
    397static inline void msm_mdp_unregister(void) {}
    398#endif
    399
    400#ifdef CONFIG_DRM_MSM_DPU
    401void msm_dpu_register(void);
    402void msm_dpu_unregister(void);
    403#else
    404static inline void msm_dpu_register(void) {}
    405static inline void msm_dpu_unregister(void) {}
    406#endif
    407
    408#ifdef CONFIG_DRM_MSM_MDSS
    409void msm_mdss_register(void);
    410void msm_mdss_unregister(void);
    411#else
    412static inline void msm_mdss_register(void) {}
    413static inline void msm_mdss_unregister(void) {}
    414#endif
    415
    416#ifdef CONFIG_DEBUG_FS
    417void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
    418int msm_debugfs_late_init(struct drm_device *dev);
    419int msm_rd_debugfs_init(struct drm_minor *minor);
    420void msm_rd_debugfs_cleanup(struct msm_drm_private *priv);
    421__printf(3, 4)
    422void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
    423		const char *fmt, ...);
    424int msm_perf_debugfs_init(struct drm_minor *minor);
    425void msm_perf_debugfs_cleanup(struct msm_drm_private *priv);
    426#else
    427static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
    428__printf(3, 4)
    429static inline void msm_rd_dump_submit(struct msm_rd_state *rd,
    430			struct msm_gem_submit *submit,
    431			const char *fmt, ...) {}
    432static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {}
    433static inline void msm_perf_debugfs_cleanup(struct msm_drm_private *priv) {}
    434#endif
    435
    436struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
    437
    438struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
    439	const char *name);
    440void __iomem *msm_ioremap(struct platform_device *pdev, const char *name);
    441void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
    442		phys_addr_t *size);
    443void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name);
    444
    445#define msm_writel(data, addr) writel((data), (addr))
    446#define msm_readl(addr) readl((addr))
    447
    448static inline void msm_rmw(void __iomem *addr, u32 mask, u32 or)
    449{
    450	u32 val = msm_readl(addr);
    451
    452	val &= ~mask;
    453	msm_writel(val | or, addr);
    454}
    455
    456/**
    457 * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work
    458 *
    459 * @timer: hrtimer to control when the kthread work is triggered
    460 * @work:  the kthread work
    461 * @worker: the kthread worker the work will be scheduled on
    462 */
    463struct msm_hrtimer_work {
    464	struct hrtimer timer;
    465	struct kthread_work work;
    466	struct kthread_worker *worker;
    467};
    468
    469void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
    470			    ktime_t wakeup_time,
    471			    enum hrtimer_mode mode);
    472void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
    473			   struct kthread_worker *worker,
    474			   kthread_work_func_t fn,
    475			   clockid_t clock_id,
    476			   enum hrtimer_mode mode);
    477
    478#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
    479#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
    480
    481static inline int align_pitch(int width, int bpp)
    482{
    483	int bytespp = (bpp + 7) / 8;
    484	/* adreno needs pitch aligned to 32 pixels: */
    485	return bytespp * ALIGN(width, 32);
    486}
    487
    488/* for the generated headers: */
    489#define INVALID_IDX(idx) ({BUG(); 0;})
    490#define fui(x)                ({BUG(); 0;})
    491#define _mesa_float_to_half(x) ({BUG(); 0;})
    492
    493
    494#define FIELD(val, name) (((val) & name ## __MASK) >> name ## __SHIFT)
    495
    496/* for conditionally setting boolean flag(s): */
    497#define COND(bool, val) ((bool) ? (val) : 0)
    498
    499static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
    500{
    501	ktime_t now = ktime_get();
    502	s64 remaining_jiffies;
    503
    504	if (ktime_compare(*timeout, now) < 0) {
    505		remaining_jiffies = 0;
    506	} else {
    507		ktime_t rem = ktime_sub(*timeout, now);
    508		remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
    509	}
    510
    511	return clamp(remaining_jiffies, 0LL, (s64)INT_MAX);
    512}
    513
    514/* Driver helpers */
    515
    516extern const struct component_master_ops msm_drm_ops;
    517
    518int msm_pm_prepare(struct device *dev);
    519void msm_pm_complete(struct device *dev);
    520
    521int msm_drv_probe(struct device *dev,
    522	int (*kms_init)(struct drm_device *dev));
    523void msm_drv_shutdown(struct platform_device *pdev);
    524
    525
    526#endif /* __MSM_DRV_H__ */