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

pl111_display.c (15676B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
      4 *
      5 * Parts of this file were based on sources as follows:
      6 *
      7 * Copyright (c) 2006-2008 Intel Corporation
      8 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
      9 * Copyright (C) 2011 Texas Instruments
     10 */
     11
     12#include <linux/clk.h>
     13#include <linux/delay.h>
     14#include <linux/dma-buf.h>
     15#include <linux/of_graph.h>
     16
     17#include <drm/drm_fb_cma_helper.h>
     18#include <drm/drm_fourcc.h>
     19#include <drm/drm_gem_atomic_helper.h>
     20#include <drm/drm_gem_cma_helper.h>
     21#include <drm/drm_vblank.h>
     22
     23#include "pl111_drm.h"
     24
     25irqreturn_t pl111_irq(int irq, void *data)
     26{
     27	struct pl111_drm_dev_private *priv = data;
     28	u32 irq_stat;
     29	irqreturn_t status = IRQ_NONE;
     30
     31	irq_stat = readl(priv->regs + CLCD_PL111_MIS);
     32
     33	if (!irq_stat)
     34		return IRQ_NONE;
     35
     36	if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE) {
     37		drm_crtc_handle_vblank(&priv->pipe.crtc);
     38
     39		status = IRQ_HANDLED;
     40	}
     41
     42	/* Clear the interrupt once done */
     43	writel(irq_stat, priv->regs + CLCD_PL111_ICR);
     44
     45	return status;
     46}
     47
     48static enum drm_mode_status
     49pl111_mode_valid(struct drm_simple_display_pipe *pipe,
     50		 const struct drm_display_mode *mode)
     51{
     52	struct drm_device *drm = pipe->crtc.dev;
     53	struct pl111_drm_dev_private *priv = drm->dev_private;
     54	u32 cpp = priv->variant->fb_bpp / 8;
     55	u64 bw;
     56
     57	/*
     58	 * We use the pixelclock to also account for interlaced modes, the
     59	 * resulting bandwidth is in bytes per second.
     60	 */
     61	bw = mode->clock * 1000ULL; /* In Hz */
     62	bw = bw * mode->hdisplay * mode->vdisplay * cpp;
     63	bw = div_u64(bw, mode->htotal * mode->vtotal);
     64
     65	/*
     66	 * If no bandwidth constraints, anything goes, else
     67	 * check if we are too fast.
     68	 */
     69	if (priv->memory_bw && (bw > priv->memory_bw)) {
     70		DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu too fast\n",
     71			      mode->hdisplay, mode->vdisplay,
     72			      mode->clock * 1000, cpp, bw);
     73
     74		return MODE_BAD;
     75	}
     76	DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu bytes/s OK\n",
     77		      mode->hdisplay, mode->vdisplay,
     78		      mode->clock * 1000, cpp, bw);
     79
     80	return MODE_OK;
     81}
     82
     83static int pl111_display_check(struct drm_simple_display_pipe *pipe,
     84			       struct drm_plane_state *pstate,
     85			       struct drm_crtc_state *cstate)
     86{
     87	const struct drm_display_mode *mode = &cstate->mode;
     88	struct drm_framebuffer *old_fb = pipe->plane.state->fb;
     89	struct drm_framebuffer *fb = pstate->fb;
     90
     91	if (mode->hdisplay % 16)
     92		return -EINVAL;
     93
     94	if (fb) {
     95		u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
     96
     97		/* FB base address must be dword aligned. */
     98		if (offset & 3)
     99			return -EINVAL;
    100
    101		/* There's no pitch register -- the mode's hdisplay
    102		 * controls it.
    103		 */
    104		if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0])
    105			return -EINVAL;
    106
    107		/* We can't change the FB format in a flicker-free
    108		 * manner (and only update it during CRTC enable).
    109		 */
    110		if (old_fb && old_fb->format != fb->format)
    111			cstate->mode_changed = true;
    112	}
    113
    114	return 0;
    115}
    116
    117static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
    118				 struct drm_crtc_state *cstate,
    119				 struct drm_plane_state *plane_state)
    120{
    121	struct drm_crtc *crtc = &pipe->crtc;
    122	struct drm_plane *plane = &pipe->plane;
    123	struct drm_device *drm = crtc->dev;
    124	struct pl111_drm_dev_private *priv = drm->dev_private;
    125	const struct drm_display_mode *mode = &cstate->mode;
    126	struct drm_framebuffer *fb = plane->state->fb;
    127	struct drm_connector *connector = priv->connector;
    128	struct drm_bridge *bridge = priv->bridge;
    129	bool grayscale = false;
    130	u32 cntl;
    131	u32 ppl, hsw, hfp, hbp;
    132	u32 lpp, vsw, vfp, vbp;
    133	u32 cpl, tim2;
    134	int ret;
    135
    136	ret = clk_set_rate(priv->clk, mode->clock * 1000);
    137	if (ret) {
    138		dev_err(drm->dev,
    139			"Failed to set pixel clock rate to %d: %d\n",
    140			mode->clock * 1000, ret);
    141	}
    142
    143	clk_prepare_enable(priv->clk);
    144
    145	ppl = (mode->hdisplay / 16) - 1;
    146	hsw = mode->hsync_end - mode->hsync_start - 1;
    147	hfp = mode->hsync_start - mode->hdisplay - 1;
    148	hbp = mode->htotal - mode->hsync_end - 1;
    149
    150	lpp = mode->vdisplay - 1;
    151	vsw = mode->vsync_end - mode->vsync_start - 1;
    152	vfp = mode->vsync_start - mode->vdisplay;
    153	vbp = mode->vtotal - mode->vsync_end;
    154
    155	cpl = mode->hdisplay - 1;
    156
    157	writel((ppl << 2) |
    158	       (hsw << 8) |
    159	       (hfp << 16) |
    160	       (hbp << 24),
    161	       priv->regs + CLCD_TIM0);
    162	writel(lpp |
    163	       (vsw << 10) |
    164	       (vfp << 16) |
    165	       (vbp << 24),
    166	       priv->regs + CLCD_TIM1);
    167
    168	spin_lock(&priv->tim2_lock);
    169
    170	tim2 = readl(priv->regs + CLCD_TIM2);
    171	tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);
    172
    173	if (priv->variant->broken_clockdivider)
    174		tim2 |= TIM2_BCD;
    175
    176	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
    177		tim2 |= TIM2_IHS;
    178
    179	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
    180		tim2 |= TIM2_IVS;
    181
    182	if (connector) {
    183		if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
    184			tim2 |= TIM2_IOE;
    185
    186		if (connector->display_info.bus_flags &
    187		    DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
    188			tim2 |= TIM2_IPC;
    189
    190		if (connector->display_info.num_bus_formats == 1 &&
    191		    connector->display_info.bus_formats[0] ==
    192		    MEDIA_BUS_FMT_Y8_1X8)
    193			grayscale = true;
    194
    195		/*
    196		 * The AC pin bias frequency is set to max count when using
    197		 * grayscale so at least once in a while we will reverse
    198		 * polarity and get rid of any DC built up that could
    199		 * damage the display.
    200		 */
    201		if (grayscale)
    202			tim2 |= TIM2_ACB_MASK;
    203	}
    204
    205	if (bridge) {
    206		const struct drm_bridge_timings *btimings = bridge->timings;
    207
    208		/*
    209		 * Here is when things get really fun. Sometimes the bridge
    210		 * timings are such that the signal out from PL11x is not
    211		 * stable before the receiving bridge (such as a dumb VGA DAC
    212		 * or similar) samples it. If that happens, we compensate by
    213		 * the only method we have: output the data on the opposite
    214		 * edge of the clock so it is for sure stable when it gets
    215		 * sampled.
    216		 *
    217		 * The PL111 manual does not contain proper timining diagrams
    218		 * or data for these details, but we know from experiments
    219		 * that the setup time is more than 3000 picoseconds (3 ns).
    220		 * If we have a bridge that requires the signal to be stable
    221		 * earlier than 3000 ps before the clock pulse, we have to
    222		 * output the data on the opposite edge to avoid flicker.
    223		 */
    224		if (btimings && btimings->setup_time_ps >= 3000)
    225			tim2 ^= TIM2_IPC;
    226	}
    227
    228	tim2 |= cpl << 16;
    229	writel(tim2, priv->regs + CLCD_TIM2);
    230	spin_unlock(&priv->tim2_lock);
    231
    232	writel(0, priv->regs + CLCD_TIM3);
    233
    234	/*
    235	 * Detect grayscale bus format. We do not support a grayscale mode
    236	 * toward userspace, instead we expose an RGB24 buffer and then the
    237	 * hardware will activate its grayscaler to convert to the grayscale
    238	 * format.
    239	 */
    240	if (grayscale)
    241		cntl = CNTL_LCDEN | CNTL_LCDMONO8;
    242	else
    243		/* Else we assume TFT display */
    244		cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1);
    245
    246	/* On the ST Micro variant, assume all 24 bits are connected */
    247	if (priv->variant->st_bitmux_control)
    248		cntl |= CNTL_ST_CDWID_24;
    249
    250	/*
    251	 * Note that the the ARM hardware's format reader takes 'r' from
    252	 * the low bit, while DRM formats list channels from high bit
    253	 * to low bit as you read left to right. The ST Micro version of
    254	 * the PL110 (LCDC) however uses the standard DRM format.
    255	 */
    256	switch (fb->format->format) {
    257	case DRM_FORMAT_BGR888:
    258		/* Only supported on the ST Micro variant */
    259		if (priv->variant->st_bitmux_control)
    260			cntl |= CNTL_ST_LCDBPP24_PACKED | CNTL_BGR;
    261		break;
    262	case DRM_FORMAT_RGB888:
    263		/* Only supported on the ST Micro variant */
    264		if (priv->variant->st_bitmux_control)
    265			cntl |= CNTL_ST_LCDBPP24_PACKED;
    266		break;
    267	case DRM_FORMAT_ABGR8888:
    268	case DRM_FORMAT_XBGR8888:
    269		if (priv->variant->st_bitmux_control)
    270			cntl |= CNTL_LCDBPP24 | CNTL_BGR;
    271		else
    272			cntl |= CNTL_LCDBPP24;
    273		break;
    274	case DRM_FORMAT_ARGB8888:
    275	case DRM_FORMAT_XRGB8888:
    276		if (priv->variant->st_bitmux_control)
    277			cntl |= CNTL_LCDBPP24;
    278		else
    279			cntl |= CNTL_LCDBPP24 | CNTL_BGR;
    280		break;
    281	case DRM_FORMAT_BGR565:
    282		if (priv->variant->is_pl110)
    283			cntl |= CNTL_LCDBPP16;
    284		else if (priv->variant->st_bitmux_control)
    285			cntl |= CNTL_LCDBPP16 | CNTL_ST_1XBPP_565 | CNTL_BGR;
    286		else
    287			cntl |= CNTL_LCDBPP16_565;
    288		break;
    289	case DRM_FORMAT_RGB565:
    290		if (priv->variant->is_pl110)
    291			cntl |= CNTL_LCDBPP16 | CNTL_BGR;
    292		else if (priv->variant->st_bitmux_control)
    293			cntl |= CNTL_LCDBPP16 | CNTL_ST_1XBPP_565;
    294		else
    295			cntl |= CNTL_LCDBPP16_565 | CNTL_BGR;
    296		break;
    297	case DRM_FORMAT_ABGR1555:
    298	case DRM_FORMAT_XBGR1555:
    299		cntl |= CNTL_LCDBPP16;
    300		if (priv->variant->st_bitmux_control)
    301			cntl |= CNTL_ST_1XBPP_5551 | CNTL_BGR;
    302		break;
    303	case DRM_FORMAT_ARGB1555:
    304	case DRM_FORMAT_XRGB1555:
    305		cntl |= CNTL_LCDBPP16;
    306		if (priv->variant->st_bitmux_control)
    307			cntl |= CNTL_ST_1XBPP_5551;
    308		else
    309			cntl |= CNTL_BGR;
    310		break;
    311	case DRM_FORMAT_ABGR4444:
    312	case DRM_FORMAT_XBGR4444:
    313		cntl |= CNTL_LCDBPP16_444;
    314		if (priv->variant->st_bitmux_control)
    315			cntl |= CNTL_ST_1XBPP_444 | CNTL_BGR;
    316		break;
    317	case DRM_FORMAT_ARGB4444:
    318	case DRM_FORMAT_XRGB4444:
    319		cntl |= CNTL_LCDBPP16_444;
    320		if (priv->variant->st_bitmux_control)
    321			cntl |= CNTL_ST_1XBPP_444;
    322		else
    323			cntl |= CNTL_BGR;
    324		break;
    325	default:
    326		WARN_ONCE(true, "Unknown FB format 0x%08x\n",
    327			  fb->format->format);
    328		break;
    329	}
    330
    331	/* The PL110 in Integrator/Versatile does the BGR routing externally */
    332	if (priv->variant->external_bgr)
    333		cntl &= ~CNTL_BGR;
    334
    335	/* Power sequence: first enable and chill */
    336	writel(cntl, priv->regs + priv->ctrl);
    337
    338	/*
    339	 * We expect this delay to stabilize the contrast
    340	 * voltage Vee as stipulated by the manual
    341	 */
    342	msleep(20);
    343
    344	if (priv->variant_display_enable)
    345		priv->variant_display_enable(drm, fb->format->format);
    346
    347	/* Power Up */
    348	cntl |= CNTL_LCDPWR;
    349	writel(cntl, priv->regs + priv->ctrl);
    350
    351	if (!priv->variant->broken_vblank)
    352		drm_crtc_vblank_on(crtc);
    353}
    354
    355static void pl111_display_disable(struct drm_simple_display_pipe *pipe)
    356{
    357	struct drm_crtc *crtc = &pipe->crtc;
    358	struct drm_device *drm = crtc->dev;
    359	struct pl111_drm_dev_private *priv = drm->dev_private;
    360	u32 cntl;
    361
    362	if (!priv->variant->broken_vblank)
    363		drm_crtc_vblank_off(crtc);
    364
    365	/* Power Down */
    366	cntl = readl(priv->regs + priv->ctrl);
    367	if (cntl & CNTL_LCDPWR) {
    368		cntl &= ~CNTL_LCDPWR;
    369		writel(cntl, priv->regs + priv->ctrl);
    370	}
    371
    372	/*
    373	 * We expect this delay to stabilize the contrast voltage Vee as
    374	 * stipulated by the manual
    375	 */
    376	msleep(20);
    377
    378	if (priv->variant_display_disable)
    379		priv->variant_display_disable(drm);
    380
    381	/* Disable */
    382	writel(0, priv->regs + priv->ctrl);
    383
    384	clk_disable_unprepare(priv->clk);
    385}
    386
    387static void pl111_display_update(struct drm_simple_display_pipe *pipe,
    388				 struct drm_plane_state *old_pstate)
    389{
    390	struct drm_crtc *crtc = &pipe->crtc;
    391	struct drm_device *drm = crtc->dev;
    392	struct pl111_drm_dev_private *priv = drm->dev_private;
    393	struct drm_pending_vblank_event *event = crtc->state->event;
    394	struct drm_plane *plane = &pipe->plane;
    395	struct drm_plane_state *pstate = plane->state;
    396	struct drm_framebuffer *fb = pstate->fb;
    397
    398	if (fb) {
    399		u32 addr = drm_fb_cma_get_gem_addr(fb, pstate, 0);
    400
    401		writel(addr, priv->regs + CLCD_UBAS);
    402	}
    403
    404	if (event) {
    405		crtc->state->event = NULL;
    406
    407		spin_lock_irq(&crtc->dev->event_lock);
    408		if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
    409			drm_crtc_arm_vblank_event(crtc, event);
    410		else
    411			drm_crtc_send_vblank_event(crtc, event);
    412		spin_unlock_irq(&crtc->dev->event_lock);
    413	}
    414}
    415
    416static int pl111_display_enable_vblank(struct drm_simple_display_pipe *pipe)
    417{
    418	struct drm_crtc *crtc = &pipe->crtc;
    419	struct drm_device *drm = crtc->dev;
    420	struct pl111_drm_dev_private *priv = drm->dev_private;
    421
    422	writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb);
    423
    424	return 0;
    425}
    426
    427static void pl111_display_disable_vblank(struct drm_simple_display_pipe *pipe)
    428{
    429	struct drm_crtc *crtc = &pipe->crtc;
    430	struct drm_device *drm = crtc->dev;
    431	struct pl111_drm_dev_private *priv = drm->dev_private;
    432
    433	writel(0, priv->regs + priv->ienb);
    434}
    435
    436static struct drm_simple_display_pipe_funcs pl111_display_funcs = {
    437	.mode_valid = pl111_mode_valid,
    438	.check = pl111_display_check,
    439	.enable = pl111_display_enable,
    440	.disable = pl111_display_disable,
    441	.update = pl111_display_update,
    442};
    443
    444static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate,
    445				    unsigned long *prate, bool set_parent)
    446{
    447	int best_div = 1, div;
    448	struct clk_hw *parent = clk_hw_get_parent(hw);
    449	unsigned long best_prate = 0;
    450	unsigned long best_diff = ~0ul;
    451	int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1;
    452
    453	for (div = 1; div < max_div; div++) {
    454		unsigned long this_prate, div_rate, diff;
    455
    456		if (set_parent)
    457			this_prate = clk_hw_round_rate(parent, rate * div);
    458		else
    459			this_prate = *prate;
    460		div_rate = DIV_ROUND_UP_ULL(this_prate, div);
    461		diff = abs(rate - div_rate);
    462
    463		if (diff < best_diff) {
    464			best_div = div;
    465			best_diff = diff;
    466			best_prate = this_prate;
    467		}
    468	}
    469
    470	*prate = best_prate;
    471	return best_div;
    472}
    473
    474static long pl111_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
    475				     unsigned long *prate)
    476{
    477	int div = pl111_clk_div_choose_div(hw, rate, prate, true);
    478
    479	return DIV_ROUND_UP_ULL(*prate, div);
    480}
    481
    482static unsigned long pl111_clk_div_recalc_rate(struct clk_hw *hw,
    483					       unsigned long prate)
    484{
    485	struct pl111_drm_dev_private *priv =
    486		container_of(hw, struct pl111_drm_dev_private, clk_div);
    487	u32 tim2 = readl(priv->regs + CLCD_TIM2);
    488	int div;
    489
    490	if (tim2 & TIM2_BCD)
    491		return prate;
    492
    493	div = tim2 & TIM2_PCD_LO_MASK;
    494	div |= (tim2 & TIM2_PCD_HI_MASK) >>
    495		(TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS);
    496	div += 2;
    497
    498	return DIV_ROUND_UP_ULL(prate, div);
    499}
    500
    501static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
    502				  unsigned long prate)
    503{
    504	struct pl111_drm_dev_private *priv =
    505		container_of(hw, struct pl111_drm_dev_private, clk_div);
    506	int div = pl111_clk_div_choose_div(hw, rate, &prate, false);
    507	u32 tim2;
    508
    509	spin_lock(&priv->tim2_lock);
    510	tim2 = readl(priv->regs + CLCD_TIM2);
    511	tim2 &= ~(TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);
    512
    513	if (div == 1) {
    514		tim2 |= TIM2_BCD;
    515	} else {
    516		div -= 2;
    517		tim2 |= div & TIM2_PCD_LO_MASK;
    518		tim2 |= (div >> TIM2_PCD_LO_BITS) << TIM2_PCD_HI_SHIFT;
    519	}
    520
    521	writel(tim2, priv->regs + CLCD_TIM2);
    522	spin_unlock(&priv->tim2_lock);
    523
    524	return 0;
    525}
    526
    527static const struct clk_ops pl111_clk_div_ops = {
    528	.recalc_rate = pl111_clk_div_recalc_rate,
    529	.round_rate = pl111_clk_div_round_rate,
    530	.set_rate = pl111_clk_div_set_rate,
    531};
    532
    533static int
    534pl111_init_clock_divider(struct drm_device *drm)
    535{
    536	struct pl111_drm_dev_private *priv = drm->dev_private;
    537	struct clk *parent = devm_clk_get(drm->dev, "clcdclk");
    538	struct clk_hw *div = &priv->clk_div;
    539	const char *parent_name;
    540	struct clk_init_data init = {
    541		.name = "pl111_div",
    542		.ops = &pl111_clk_div_ops,
    543		.parent_names = &parent_name,
    544		.num_parents = 1,
    545		.flags = CLK_SET_RATE_PARENT,
    546	};
    547	int ret;
    548
    549	if (IS_ERR(parent)) {
    550		dev_err(drm->dev, "CLCD: unable to get clcdclk.\n");
    551		return PTR_ERR(parent);
    552	}
    553
    554	spin_lock_init(&priv->tim2_lock);
    555
    556	/* If the clock divider is broken, use the parent directly */
    557	if (priv->variant->broken_clockdivider) {
    558		priv->clk = parent;
    559		return 0;
    560	}
    561	parent_name = __clk_get_name(parent);
    562	div->init = &init;
    563
    564	ret = devm_clk_hw_register(drm->dev, div);
    565
    566	priv->clk = div->clk;
    567	return ret;
    568}
    569
    570int pl111_display_init(struct drm_device *drm)
    571{
    572	struct pl111_drm_dev_private *priv = drm->dev_private;
    573	int ret;
    574
    575	ret = pl111_init_clock_divider(drm);
    576	if (ret)
    577		return ret;
    578
    579	if (!priv->variant->broken_vblank) {
    580		pl111_display_funcs.enable_vblank = pl111_display_enable_vblank;
    581		pl111_display_funcs.disable_vblank = pl111_display_disable_vblank;
    582	}
    583
    584	ret = drm_simple_display_pipe_init(drm, &priv->pipe,
    585					   &pl111_display_funcs,
    586					   priv->variant->formats,
    587					   priv->variant->nformats,
    588					   NULL,
    589					   priv->connector);
    590	if (ret)
    591		return ret;
    592
    593	return 0;
    594}