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

t1042rdb_diu.c (3705B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * T1042 platform DIU operation
      4 *
      5 * Copyright 2014 Freescale Semiconductor Inc.
      6 */
      7
      8#include <linux/init.h>
      9#include <linux/io.h>
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/of.h>
     13#include <linux/of_address.h>
     14
     15#include <sysdev/fsl_soc.h>
     16
     17/*DIU Pixel ClockCR offset in scfg*/
     18#define CCSR_SCFG_PIXCLKCR      0x28
     19
     20/* DIU Pixel Clock bits of the PIXCLKCR */
     21#define PIXCLKCR_PXCKEN		0x80000000
     22#define PIXCLKCR_PXCKINV	0x40000000
     23#define PIXCLKCR_PXCKDLY	0x0000FF00
     24#define PIXCLKCR_PXCLK_MASK	0x00FF0000
     25
     26/* Some CPLD register definitions */
     27#define CPLD_DIUCSR		0x16
     28#define CPLD_DIUCSR_DVIEN	0x80
     29#define CPLD_DIUCSR_BACKLIGHT	0x0f
     30
     31struct device_node *cpld_node;
     32
     33/**
     34 * t1042rdb_set_monitor_port: switch the output to a different monitor port
     35 */
     36static void t1042rdb_set_monitor_port(enum fsl_diu_monitor_port port)
     37{
     38	void __iomem *cpld_base;
     39
     40	cpld_base = of_iomap(cpld_node, 0);
     41	if (!cpld_base) {
     42		pr_err("%s: Could not map cpld registers\n", __func__);
     43		goto exit;
     44	}
     45
     46	switch (port) {
     47	case FSL_DIU_PORT_DVI:
     48		/* Enable the DVI(HDMI) port, disable the DFP and
     49		 * the backlight
     50		 */
     51		clrbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_DVIEN);
     52		break;
     53	case FSL_DIU_PORT_LVDS:
     54		/*
     55		 * LVDS also needs backlight enabled, otherwise the display
     56		 * will be blank.
     57		 */
     58		/* Enable the DFP port, disable the DVI*/
     59		setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 8);
     60		setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 4);
     61		setbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_BACKLIGHT);
     62		break;
     63	default:
     64		pr_err("%s: Unsupported monitor port %i\n", __func__, port);
     65	}
     66
     67	iounmap(cpld_base);
     68exit:
     69	of_node_put(cpld_node);
     70}
     71
     72/**
     73 * t1042rdb_set_pixel_clock: program the DIU's clock
     74 * @pixclock: pixel clock in ps (pico seconds)
     75 */
     76static void t1042rdb_set_pixel_clock(unsigned int pixclock)
     77{
     78	struct device_node *scfg_np;
     79	void __iomem *scfg;
     80	unsigned long freq;
     81	u64 temp;
     82	u32 pxclk;
     83
     84	scfg_np = of_find_compatible_node(NULL, NULL, "fsl,t1040-scfg");
     85	if (!scfg_np) {
     86		pr_err("%s: Missing scfg node. Can not display video.\n",
     87		       __func__);
     88		return;
     89	}
     90
     91	scfg = of_iomap(scfg_np, 0);
     92	of_node_put(scfg_np);
     93	if (!scfg) {
     94		pr_err("%s: Could not map device. Can not display video.\n",
     95		       __func__);
     96		return;
     97	}
     98
     99	/* Convert pixclock into frequency */
    100	temp = 1000000000000ULL;
    101	do_div(temp, pixclock);
    102	freq = temp;
    103
    104	/*
    105	 * 'pxclk' is the ratio of the platform clock to the pixel clock.
    106	 * This number is programmed into the PIXCLKCR register, and the valid
    107	 * range of values is 2-255.
    108	 */
    109	pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
    110	pxclk = clamp_t(u32, pxclk, 2, 255);
    111
    112	/* Disable the pixel clock, and set it to non-inverted and no delay */
    113	clrbits32(scfg + CCSR_SCFG_PIXCLKCR,
    114		  PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK);
    115
    116	/* Enable the clock and set the pxclk */
    117	setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
    118
    119	iounmap(scfg);
    120}
    121
    122/**
    123 * t1042rdb_valid_monitor_port: set the monitor port for sysfs
    124 */
    125static enum fsl_diu_monitor_port
    126t1042rdb_valid_monitor_port(enum fsl_diu_monitor_port port)
    127{
    128	switch (port) {
    129	case FSL_DIU_PORT_DVI:
    130	case FSL_DIU_PORT_LVDS:
    131		return port;
    132	default:
    133		return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
    134	}
    135}
    136
    137static int __init t1042rdb_diu_init(void)
    138{
    139	cpld_node = of_find_compatible_node(NULL, NULL, "fsl,t1042rdb-cpld");
    140	if (!cpld_node)
    141		return 0;
    142
    143	diu_ops.set_monitor_port	= t1042rdb_set_monitor_port;
    144	diu_ops.set_pixel_clock		= t1042rdb_set_pixel_clock;
    145	diu_ops.valid_monitor_port	= t1042rdb_valid_monitor_port;
    146
    147	return 0;
    148}
    149
    150early_initcall(t1042rdb_diu_init);
    151
    152MODULE_LICENSE("GPL");