123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
- */
- #ifndef _SDE_ROTATOR_R3_INTERNAL_H
- #define _SDE_ROTATOR_R3_INTERNAL_H
- #include "sde_rotator_core.h"
- struct sde_hw_rotator;
- struct sde_hw_rotator_context;
- /**
- * Flags
- */
- #define SDE_ROT_FLAG_SECURE_OVERLAY_SESSION 0x1
- #define SDE_ROT_FLAG_FLIP_LR 0x2
- #define SDE_ROT_FLAG_FLIP_UD 0x4
- #define SDE_ROT_FLAG_SOURCE_ROTATED_90 0x8
- #define SDE_ROT_FLAG_ROT_90 0x10
- #define SDE_ROT_FLAG_DEINTERLACE 0x20
- #define SDE_ROT_FLAG_SECURE_CAMERA_SESSION 0x40
- /**
- * General defines
- */
- #define SDE_HW_ROT_REGDMA_RAM_SIZE 1024
- #define SDE_HW_ROT_REGDMA_TOTAL_CTX 8
- #define SDE_HW_ROT_REGDMA_SEG_MASK (SDE_HW_ROT_REGDMA_TOTAL_CTX - 1)
- #define SDE_HW_ROT_REGDMA_SEG_SIZE \
- (SDE_HW_ROT_REGDMA_RAM_SIZE / SDE_HW_ROT_REGDMA_TOTAL_CTX)
- #define SDE_REGDMA_SWTS_MASK 0x00000FFF
- #define SDE_REGDMA_SWTS_SHIFT 12
- enum sde_rot_queue_prio {
- ROT_QUEUE_HIGH_PRIORITY,
- ROT_QUEUE_LOW_PRIORITY,
- ROT_QUEUE_MAX
- };
- enum sde_rot_angle {
- ROT_ANGLE_0,
- ROT_ANGLE_90,
- ROT_ANGEL_MAX
- };
- enum sde_rotator_regdma_mode {
- ROT_REGDMA_OFF,
- ROT_REGDMA_ON,
- ROT_REGDMA_MAX
- };
- /**
- * struct sde_hw_rot_sspp_cfg: Rotator SSPP Configration description
- * @src: source surface information
- * @src_rect: src ROI, caller takes into account the different operations
- * such as decimation, flip etc to program this field
- * @addr: source surface address
- */
- struct sde_hw_rot_sspp_cfg {
- struct sde_mdp_format_params *fmt;
- struct sde_mdp_plane_sizes src_plane;
- struct sde_rect *src_rect;
- struct sde_mdp_data *data;
- u32 img_width;
- u32 img_height;
- u32 fps;
- u64 bw;
- };
- /**
- * struct sde_hw_rot_wb_cfg: Rotator WB Configration description
- * @dest: destination surface information
- * @dest_rect: dest ROI, caller takes into account the different operations
- * such as decimation, flip etc to program this field
- * @addr: destination surface address
- * @prefill_bw: prefill bandwidth in Bps
- */
- struct sde_hw_rot_wb_cfg {
- struct sde_mdp_format_params *fmt;
- struct sde_mdp_plane_sizes dst_plane;
- struct sde_rect *dst_rect;
- struct sde_mdp_data *data;
- u32 img_width;
- u32 img_height;
- u32 v_downscale_factor;
- u32 h_downscale_factor;
- u32 fps;
- u64 bw;
- u64 prefill_bw;
- };
- /**
- *
- * struct sde_hw_rotator_ops: Interface to the Rotator Hw driver functions
- *
- * Pre-requsises:
- * - Caller must call the init function to get the rotator context
- * - These functions will be called after clocks are enabled
- */
- struct sde_hw_rotator_ops {
- /**
- * setup_rotator_fetchengine():
- * Setup Source format
- * Setup Source dimension/cropping rectangle (ROI)
- * Setup Source surface base address and stride
- * Setup fetch engine op mode (linear/tiled/compression/...)
- * @ctx: Rotator context created in sde_hw_rotator_config
- * @queue_id: Select either low / high priority queue
- * @cfg: Rotator Fetch engine configuration parameters
- * @danger_lut: Danger LUT setting
- * @safe_lut: Safe LUT setting
- * @dnsc_factor_w: Downscale factor for width
- * @dnsc_factor_h: Downscale factor for height
- * @flags: Specific config flag, see SDE_ROT_FLAG_ for details
- */
- void (*setup_rotator_fetchengine)(
- struct sde_hw_rotator_context *ctx,
- enum sde_rot_queue_prio queue_id,
- struct sde_hw_rot_sspp_cfg *cfg,
- u32 danger_lut,
- u32 safe_lut,
- u32 dnsc_factor_w,
- u32 dnsc_factor_h,
- u32 flags);
- /**
- * setup_rotator_wbengine():
- * Setup destination formats
- * Setup destination dimension/cropping rectangle (ROI)
- * Setup destination surface base address and strides
- * Setup writeback engine op mode (linear/tiled/compression)
- * @ctx: Rotator context created in sde_hw_rotator_config
- * @queue_id: Select either low / high priority queue
- * @cfg: Rotator WriteBack engine configuration parameters
- * @flags: Specific config flag, see SDE_ROT_FLAG_ for details
- */
- void (*setup_rotator_wbengine)(
- struct sde_hw_rotator_context *ctx,
- enum sde_rot_queue_prio queue_id,
- struct sde_hw_rot_wb_cfg *cfg,
- u32 flags);
- /**
- * start_rotator():
- * Kick start rotator operation based on cached setup parameters
- * REGDMA commands will get generated at this points
- * @ctx: Rotator context
- * @queue_id: Select either low / high priority queue
- * Returns: unique job timestamp per submit. Used for tracking
- * rotator finished job.
- */
- u32 (*start_rotator)(
- struct sde_hw_rotator_context *ctx,
- enum sde_rot_queue_prio queue_id);
- /**
- * wait_rotator_done():
- * Notify Rotator HAL layer previously submitted job finished.
- * A job timestamp will return to caller.
- * @ctx: Rotator context
- * @flags: Reserved
- * Returns: job timestamp for tracking purpose
- *
- */
- u32 (*wait_rotator_done)(
- struct sde_hw_rotator_context *ctx,
- enum sde_rot_queue_prio queue_id,
- u32 flags);
- /**
- * get_pending_ts():
- * Obtain current active timestamp from rotator hw
- * @rot: HW Rotator structure
- * @ctx: Rotator context
- * @ts: current timestamp return from rot hw
- * Returns: true if context has pending requests
- */
- int (*get_pending_ts)(
- struct sde_hw_rotator *rot,
- struct sde_hw_rotator_context *ctx,
- u32 *ts);
- /**
- * update_ts():
- * Update rotator timestmap with given value
- * @rot: HW Rotator structure
- * @q_id: rotator queue id
- * @ts: new timestamp for rotator
- */
- void (*update_ts)(
- struct sde_hw_rotator *rot,
- u32 q_id,
- u32 ts);
- };
- /**
- * struct sde_dbg_buf : Debug buffer used by debugfs
- * @vaddr: VA address mapped from dma buffer
- * @dmabuf: DMA buffer
- * @buflen: Length of DMA buffer
- * @width: pixel width of buffer
- * @height: pixel height of buffer
- */
- struct sde_dbg_buf {
- void *vaddr;
- struct dma_buf *dmabuf;
- unsigned long buflen;
- u32 width;
- u32 height;
- };
- /**
- * struct sde_hw_rotator_context : Each rotator context ties to each priority
- * queue. Max number of concurrent contexts in regdma is limited to regdma
- * ram segment size allocation. Each rotator context can be any priority. A
- * incremental timestamp is used to identify and assigned to each context.
- * @list: list of pending context
- * @sequence_id: unique sequence identifier for rotation request
- * @sbuf_mode: true if stream buffer is requested
- * @start_ctrl: start control register update value
- * @sys_cache_mode: sys cache mode register update value
- * @op_mode: rot top op mode selection
- * @last_entry: pointer to last configured entry (for debugging purposes)
- */
- struct sde_hw_rotator_context {
- struct list_head list;
- struct sde_hw_rotator *rot;
- struct sde_rot_hw_resource *hwres;
- enum sde_rot_queue_prio q_id;
- u32 session_id;
- u32 sequence_id;
- char __iomem *regdma_base;
- char __iomem *regdma_wrptr;
- u32 timestamp;
- struct completion rot_comp;
- wait_queue_head_t regdma_waitq;
- struct sde_dbg_buf src_dbgbuf;
- struct sde_dbg_buf dst_dbgbuf;
- u32 last_regdma_isr_status;
- u32 last_regdma_timestamp;
- dma_addr_t ts_addr;
- bool is_secure;
- bool is_traffic_shaping;
- bool sbuf_mode;
- bool abort;
- u32 start_ctrl;
- u32 sys_cache_mode;
- u32 op_mode;
- struct sde_rot_entry *last_entry;
- };
- /**
- * struct sde_hw_rotator_resource_info : Each rotator resource ties to each
- * priority queue
- */
- struct sde_hw_rotator_resource_info {
- struct sde_hw_rotator *rot;
- struct sde_rot_hw_resource hw;
- };
- /**
- * struct sde_hw_rotator : Rotator description
- * @hw: mdp register mapped offset
- * @ops: pointer to operations possible for the rotator HW
- * @highest_bank: highest bank size of memory
- * @ubwc_malsize: ubwc minimum allowable length
- * @ubwc_swizzle: ubwc swizzle enable
- * @sbuf_headroom: stream buffer headroom in lines
- * @solid_fill: true if solid fill is requested
- * @constant_color: solid fill constant color
- * @sbuf_ctx: list of active sbuf context in FIFO order
- * @vid_trigger: video mode trigger select
- * @cmd_trigger: command mode trigger select
- * @inpixfmts: array of supported input pixel formats fourcc per mode
- * @num_inpixfmt: size of the supported input pixel format array per mode
- * @outpixfmts: array of supported output pixel formats in fourcc per mode
- * @num_outpixfmt: size of the supported output pixel formats array per mode
- * @downscale_caps: capability string of scaling
- * @maxlinewidth: maximum line width supported
- */
- struct sde_hw_rotator {
- /* base */
- char __iomem *mdss_base;
- /* Platform device from upper manager */
- struct platform_device *pdev;
- /* Ops */
- struct sde_hw_rotator_ops ops;
- /* Cmd Queue */
- u32 cmd_queue[SDE_HW_ROT_REGDMA_RAM_SIZE];
- /* Cmd Queue Write Ptr */
- char __iomem *cmd_wr_ptr[ROT_QUEUE_MAX][SDE_HW_ROT_REGDMA_TOTAL_CTX];
- /* Rotator Context */
- struct sde_hw_rotator_context
- *rotCtx[ROT_QUEUE_MAX][SDE_HW_ROT_REGDMA_TOTAL_CTX];
- /* Cmd timestamp sequence for different priority*/
- atomic_t timestamp[ROT_QUEUE_MAX];
- /* regdma mode */
- enum sde_rotator_regdma_mode mode;
- /* logical interrupt number */
- int irq_num;
- atomic_t irq_enabled;
- /* internal ION memory for SW timestamp */
- struct ion_client *iclient;
- struct sde_mdp_img_data swts_buf;
- void *swts_buffer;
- u32 highest_bank;
- u32 ubwc_malsize;
- u32 ubwc_swizzle;
- u32 sbuf_headroom;
- u32 solid_fill;
- u32 constant_color;
- spinlock_t rotctx_lock;
- spinlock_t rotisr_lock;
- bool dbgmem;
- bool reset_hw_ts;
- u32 last_hwts[ROT_QUEUE_MAX];
- u32 koff_timeout;
- u32 vid_trigger;
- u32 cmd_trigger;
- struct list_head sbuf_ctx[ROT_QUEUE_MAX];
- const u32 *inpixfmts[SDE_ROTATOR_MODE_MAX];
- u32 num_inpixfmt[SDE_ROTATOR_MODE_MAX];
- const u32 *outpixfmts[SDE_ROTATOR_MODE_MAX];
- u32 num_outpixfmt[SDE_ROTATOR_MODE_MAX];
- const char *downscale_caps;
- u32 maxlinewidth;
- };
- /**
- * sde_hw_rotator_get_regdma_ctxidx(): regdma segment index is based on
- * timestamp. For non-regdma, just return 0 (i.e. first index)
- * @ctx: Rotator Context
- * return: regdma segment index
- */
- static inline u32 sde_hw_rotator_get_regdma_ctxidx(
- struct sde_hw_rotator_context *ctx)
- {
- if (ctx->rot->mode == ROT_REGDMA_OFF)
- return 0;
- else
- return ctx->timestamp & SDE_HW_ROT_REGDMA_SEG_MASK;
- }
- /**
- * sde_hw_rotator_get_regdma_segment_base: return the base pointe of current
- * regdma command buffer
- * @ctx: Rotator Context
- * return: base segment address
- */
- static inline char __iomem *sde_hw_rotator_get_regdma_segment_base(
- struct sde_hw_rotator_context *ctx)
- {
- SDEROT_DBG("regdma base @slot[%d]: %pK\n",
- sde_hw_rotator_get_regdma_ctxidx(ctx),
- ctx->regdma_base);
- return ctx->regdma_base;
- }
- /**
- * sde_hw_rotator_get_regdma_segment(): return current regdma command buffer
- * pointer for current regdma segment.
- * @ctx: Rotator Context
- * return: segment address
- */
- static inline char __iomem *sde_hw_rotator_get_regdma_segment(
- struct sde_hw_rotator_context *ctx)
- {
- u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
- char __iomem *addr = ctx->regdma_wrptr;
- SDEROT_DBG("regdma slot[%d] ==> %pK\n", idx, addr);
- return addr;
- }
- /**
- * sde_hw_rotator_put_regdma_segment(): update current regdma command buffer
- * pointer for current regdma segment
- * @ctx: Rotator Context
- * @wrptr: current regdma segment location
- */
- static inline void sde_hw_rotator_put_regdma_segment(
- struct sde_hw_rotator_context *ctx,
- char __iomem *wrptr)
- {
- u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
- ctx->regdma_wrptr = wrptr;
- SDEROT_DBG("regdma slot[%d] <== %pK\n", idx, wrptr);
- }
- /**
- * sde_hw_rotator_put_ctx(): Storing rotator context according to its
- * timestamp.
- */
- static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx)
- {
- struct sde_hw_rotator *rot = ctx->rot;
- u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
- unsigned long flags;
- spin_lock_irqsave(&rot->rotisr_lock, flags);
- rot->rotCtx[ctx->q_id][idx] = ctx;
- if (ctx->sbuf_mode)
- list_add_tail(&ctx->list, &rot->sbuf_ctx[ctx->q_id]);
- spin_unlock_irqrestore(&rot->rotisr_lock, flags);
- SDEROT_DBG("rotCtx[%d][%d] <== ctx:%pK | session-id:%d\n",
- ctx->q_id, idx, ctx, ctx->session_id);
- }
- /**
- * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its
- * timestamp.
- */
- static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx)
- {
- struct sde_hw_rotator *rot = ctx->rot;
- u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
- unsigned long flags;
- spin_lock_irqsave(&rot->rotisr_lock, flags);
- rot->rotCtx[ctx->q_id][idx] = NULL;
- if (ctx->sbuf_mode)
- list_del_init(&ctx->list);
- spin_unlock_irqrestore(&rot->rotisr_lock, flags);
- SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n",
- ctx->q_id, idx, ctx->session_id);
- }
- #endif /*_SDE_ROTATOR_R3_INTERNAL_H */
|