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

dcss-ss.c (4567B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2019 NXP.
      4 */
      5
      6#include <linux/device.h>
      7#include <linux/slab.h>
      8
      9#include "dcss-dev.h"
     10
     11#define DCSS_SS_SYS_CTRL			0x00
     12#define   RUN_EN				BIT(0)
     13#define DCSS_SS_DISPLAY				0x10
     14#define   LRC_X_POS				0
     15#define   LRC_X_MASK				GENMASK(12, 0)
     16#define   LRC_Y_POS				16
     17#define   LRC_Y_MASK				GENMASK(28, 16)
     18#define DCSS_SS_HSYNC				0x20
     19#define DCSS_SS_VSYNC				0x30
     20#define   SYNC_START_POS			0
     21#define   SYNC_START_MASK			GENMASK(12, 0)
     22#define   SYNC_END_POS				16
     23#define   SYNC_END_MASK				GENMASK(28, 16)
     24#define   SYNC_POL				BIT(31)
     25#define DCSS_SS_DE_ULC				0x40
     26#define   ULC_X_POS				0
     27#define   ULC_X_MASK				GENMASK(12, 0)
     28#define   ULC_Y_POS				16
     29#define   ULC_Y_MASK				GENMASK(28, 16)
     30#define   ULC_POL				BIT(31)
     31#define DCSS_SS_DE_LRC				0x50
     32#define DCSS_SS_MODE				0x60
     33#define   PIPE_MODE_POS				0
     34#define   PIPE_MODE_MASK			GENMASK(1, 0)
     35#define DCSS_SS_COEFF				0x70
     36#define   HORIZ_A_POS				0
     37#define   HORIZ_A_MASK				GENMASK(3, 0)
     38#define   HORIZ_B_POS				4
     39#define   HORIZ_B_MASK				GENMASK(7, 4)
     40#define   HORIZ_C_POS				8
     41#define   HORIZ_C_MASK				GENMASK(11, 8)
     42#define   HORIZ_H_NORM_POS			12
     43#define   HORIZ_H_NORM_MASK			GENMASK(14, 12)
     44#define   VERT_A_POS				16
     45#define   VERT_A_MASK				GENMASK(19, 16)
     46#define   VERT_B_POS				20
     47#define   VERT_B_MASK				GENMASK(23, 20)
     48#define   VERT_C_POS				24
     49#define   VERT_C_MASK				GENMASK(27, 24)
     50#define   VERT_H_NORM_POS			28
     51#define   VERT_H_NORM_MASK			GENMASK(30, 28)
     52#define DCSS_SS_CLIP_CB				0x80
     53#define DCSS_SS_CLIP_CR				0x90
     54#define   CLIP_MIN_POS				0
     55#define   CLIP_MIN_MASK				GENMASK(9, 0)
     56#define   CLIP_MAX_POS				0
     57#define   CLIP_MAX_MASK				GENMASK(23, 16)
     58#define DCSS_SS_INTER_MODE			0xA0
     59#define   INT_EN				BIT(0)
     60#define   VSYNC_SHIFT				BIT(1)
     61
     62struct dcss_ss {
     63	struct device *dev;
     64	void __iomem *base_reg;
     65	u32 base_ofs;
     66
     67	struct dcss_ctxld *ctxld;
     68	u32 ctx_id;
     69
     70	bool in_use;
     71};
     72
     73static void dcss_ss_write(struct dcss_ss *ss, u32 val, u32 ofs)
     74{
     75	if (!ss->in_use)
     76		dcss_writel(val, ss->base_reg + ofs);
     77
     78	dcss_ctxld_write(ss->ctxld, ss->ctx_id, val,
     79			 ss->base_ofs + ofs);
     80}
     81
     82int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base)
     83{
     84	struct dcss_ss *ss;
     85
     86	ss = kzalloc(sizeof(*ss), GFP_KERNEL);
     87	if (!ss)
     88		return -ENOMEM;
     89
     90	dcss->ss = ss;
     91	ss->dev = dcss->dev;
     92	ss->ctxld = dcss->ctxld;
     93
     94	ss->base_reg = ioremap(ss_base, SZ_4K);
     95	if (!ss->base_reg) {
     96		dev_err(dcss->dev, "ss: unable to remap ss base\n");
     97		kfree(ss);
     98		return -ENOMEM;
     99	}
    100
    101	ss->base_ofs = ss_base;
    102	ss->ctx_id = CTX_SB_HP;
    103
    104	return 0;
    105}
    106
    107void dcss_ss_exit(struct dcss_ss *ss)
    108{
    109	/* stop SS */
    110	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);
    111
    112	if (ss->base_reg)
    113		iounmap(ss->base_reg);
    114
    115	kfree(ss);
    116}
    117
    118void dcss_ss_subsam_set(struct dcss_ss *ss)
    119{
    120	dcss_ss_write(ss, 0x41614161, DCSS_SS_COEFF);
    121	dcss_ss_write(ss, 0, DCSS_SS_MODE);
    122	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CB);
    123	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CR);
    124}
    125
    126void dcss_ss_sync_set(struct dcss_ss *ss, struct videomode *vm,
    127		      bool phsync, bool pvsync)
    128{
    129	u16 lrc_x, lrc_y;
    130	u16 hsync_start, hsync_end;
    131	u16 vsync_start, vsync_end;
    132	u16 de_ulc_x, de_ulc_y;
    133	u16 de_lrc_x, de_lrc_y;
    134
    135	lrc_x = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
    136		vm->hactive - 1;
    137	lrc_y = vm->vfront_porch + vm->vback_porch + vm->vsync_len +
    138		vm->vactive - 1;
    139
    140	dcss_ss_write(ss, (lrc_y << LRC_Y_POS) | lrc_x, DCSS_SS_DISPLAY);
    141
    142	hsync_start = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
    143		      vm->hactive - 1;
    144	hsync_end = vm->hsync_len - 1;
    145
    146	dcss_ss_write(ss, (phsync ? SYNC_POL : 0) |
    147		      ((u32)hsync_end << SYNC_END_POS) | hsync_start,
    148		      DCSS_SS_HSYNC);
    149
    150	vsync_start = vm->vfront_porch - 1;
    151	vsync_end = vm->vfront_porch + vm->vsync_len - 1;
    152
    153	dcss_ss_write(ss, (pvsync ? SYNC_POL : 0) |
    154		      ((u32)vsync_end << SYNC_END_POS) | vsync_start,
    155		      DCSS_SS_VSYNC);
    156
    157	de_ulc_x = vm->hsync_len + vm->hback_porch - 1;
    158	de_ulc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch;
    159
    160	dcss_ss_write(ss, SYNC_POL | ((u32)de_ulc_y << ULC_Y_POS) | de_ulc_x,
    161		      DCSS_SS_DE_ULC);
    162
    163	de_lrc_x = vm->hsync_len + vm->hback_porch + vm->hactive - 1;
    164	de_lrc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch +
    165		   vm->vactive - 1;
    166
    167	dcss_ss_write(ss, (de_lrc_y << LRC_Y_POS) | de_lrc_x, DCSS_SS_DE_LRC);
    168}
    169
    170void dcss_ss_enable(struct dcss_ss *ss)
    171{
    172	dcss_ss_write(ss, RUN_EN, DCSS_SS_SYS_CTRL);
    173	ss->in_use = true;
    174}
    175
    176void dcss_ss_shutoff(struct dcss_ss *ss)
    177{
    178	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);
    179	ss->in_use = false;
    180}