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

hdmi_wp.c (7441B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * HDMI wrapper
      4 *
      5 * Copyright (C) 2013 Texas Instruments Incorporated
      6 */
      7
      8#define DSS_SUBSYS_NAME "HDMIWP"
      9
     10#include <linux/kernel.h>
     11#include <linux/err.h>
     12#include <linux/io.h>
     13#include <linux/platform_device.h>
     14#include <linux/seq_file.h>
     15
     16#include <video/omapfb_dss.h>
     17
     18#include "dss.h"
     19#include "hdmi.h"
     20
     21void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s)
     22{
     23#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, hdmi_read_reg(wp->base, r))
     24
     25	DUMPREG(HDMI_WP_REVISION);
     26	DUMPREG(HDMI_WP_SYSCONFIG);
     27	DUMPREG(HDMI_WP_IRQSTATUS_RAW);
     28	DUMPREG(HDMI_WP_IRQSTATUS);
     29	DUMPREG(HDMI_WP_IRQENABLE_SET);
     30	DUMPREG(HDMI_WP_IRQENABLE_CLR);
     31	DUMPREG(HDMI_WP_IRQWAKEEN);
     32	DUMPREG(HDMI_WP_PWR_CTRL);
     33	DUMPREG(HDMI_WP_DEBOUNCE);
     34	DUMPREG(HDMI_WP_VIDEO_CFG);
     35	DUMPREG(HDMI_WP_VIDEO_SIZE);
     36	DUMPREG(HDMI_WP_VIDEO_TIMING_H);
     37	DUMPREG(HDMI_WP_VIDEO_TIMING_V);
     38	DUMPREG(HDMI_WP_CLK);
     39	DUMPREG(HDMI_WP_AUDIO_CFG);
     40	DUMPREG(HDMI_WP_AUDIO_CFG2);
     41	DUMPREG(HDMI_WP_AUDIO_CTRL);
     42	DUMPREG(HDMI_WP_AUDIO_DATA);
     43}
     44
     45u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp)
     46{
     47	return hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS);
     48}
     49
     50void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus)
     51{
     52	hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, irqstatus);
     53	/* flush posted write */
     54	hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS);
     55}
     56
     57void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask)
     58{
     59	hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_SET, mask);
     60}
     61
     62void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask)
     63{
     64	hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_CLR, mask);
     65}
     66
     67/* PHY_PWR_CMD */
     68int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val)
     69{
     70	/* Return if already the state */
     71	if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val)
     72		return 0;
     73
     74	/* Command for power control of HDMI PHY */
     75	REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6);
     76
     77	/* Status of the power control of HDMI PHY */
     78	if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val)
     79			!= val) {
     80		DSSERR("Failed to set PHY power mode to %d\n", val);
     81		return -ETIMEDOUT;
     82	}
     83
     84	return 0;
     85}
     86
     87/* PLL_PWR_CMD */
     88int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val)
     89{
     90	/* Command for power control of HDMI PLL */
     91	REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2);
     92
     93	/* wait till PHY_PWR_STATUS is set */
     94	if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val)
     95			!= val) {
     96		DSSERR("Failed to set PLL_PWR_STATUS\n");
     97		return -ETIMEDOUT;
     98	}
     99
    100	return 0;
    101}
    102
    103int hdmi_wp_video_start(struct hdmi_wp_data *wp)
    104{
    105	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, true, 31, 31);
    106
    107	return 0;
    108}
    109
    110void hdmi_wp_video_stop(struct hdmi_wp_data *wp)
    111{
    112	int i;
    113
    114	hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_FRAME_DONE);
    115
    116	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31);
    117
    118	for (i = 0; i < 50; ++i) {
    119		u32 v;
    120
    121		msleep(20);
    122
    123		v = hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS_RAW);
    124		if (v & HDMI_IRQ_VIDEO_FRAME_DONE)
    125			return;
    126	}
    127
    128	DSSERR("no HDMI FRAMEDONE when disabling output\n");
    129}
    130
    131void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
    132		struct hdmi_video_format *video_fmt)
    133{
    134	u32 l = 0;
    135
    136	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode,
    137		10, 8);
    138
    139	l |= FLD_VAL(video_fmt->y_res, 31, 16);
    140	l |= FLD_VAL(video_fmt->x_res, 15, 0);
    141	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l);
    142}
    143
    144void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
    145		struct omap_video_timings *timings)
    146{
    147	u32 r;
    148	bool vsync_pol, hsync_pol;
    149	DSSDBG("Enter hdmi_wp_video_config_interface\n");
    150
    151	vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
    152	hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
    153
    154	r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG);
    155	r = FLD_MOD(r, vsync_pol, 7, 7);
    156	r = FLD_MOD(r, hsync_pol, 6, 6);
    157	r = FLD_MOD(r, timings->interlace, 3, 3);
    158	r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
    159	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r);
    160}
    161
    162void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
    163		struct omap_video_timings *timings)
    164{
    165	u32 timing_h = 0;
    166	u32 timing_v = 0;
    167
    168	DSSDBG("Enter hdmi_wp_video_config_timing\n");
    169
    170	timing_h |= FLD_VAL(timings->hbp, 31, 20);
    171	timing_h |= FLD_VAL(timings->hfp, 19, 8);
    172	timing_h |= FLD_VAL(timings->hsw, 7, 0);
    173	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_H, timing_h);
    174
    175	timing_v |= FLD_VAL(timings->vbp, 31, 20);
    176	timing_v |= FLD_VAL(timings->vfp, 19, 8);
    177	timing_v |= FLD_VAL(timings->vsw, 7, 0);
    178	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_V, timing_v);
    179}
    180
    181void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
    182		struct omap_video_timings *timings, struct hdmi_config *param)
    183{
    184	DSSDBG("Enter hdmi_wp_video_init_format\n");
    185
    186	video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
    187	video_fmt->y_res = param->timings.y_res;
    188	video_fmt->x_res = param->timings.x_res;
    189	if (param->timings.interlace)
    190		video_fmt->y_res /= 2;
    191
    192	timings->hbp = param->timings.hbp;
    193	timings->hfp = param->timings.hfp;
    194	timings->hsw = param->timings.hsw;
    195	timings->vbp = param->timings.vbp;
    196	timings->vfp = param->timings.vfp;
    197	timings->vsw = param->timings.vsw;
    198	timings->vsync_level = param->timings.vsync_level;
    199	timings->hsync_level = param->timings.hsync_level;
    200	timings->interlace = param->timings.interlace;
    201}
    202
    203void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
    204		struct hdmi_audio_format *aud_fmt)
    205{
    206	u32 r;
    207
    208	DSSDBG("Enter hdmi_wp_audio_config_format\n");
    209
    210	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG);
    211	if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
    212	    omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
    213	    omapdss_get_version() == OMAPDSS_VER_OMAP4) {
    214		r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
    215		r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
    216	}
    217	r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
    218	r = FLD_MOD(r, aud_fmt->type, 4, 4);
    219	r = FLD_MOD(r, aud_fmt->justification, 3, 3);
    220	r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
    221	r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
    222	r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
    223	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG, r);
    224}
    225
    226void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
    227		struct hdmi_audio_dma *aud_dma)
    228{
    229	u32 r;
    230
    231	DSSDBG("Enter hdmi_wp_audio_config_dma\n");
    232
    233	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG2);
    234	r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
    235	r = FLD_MOD(r, aud_dma->block_size, 7, 0);
    236	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG2, r);
    237
    238	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CTRL);
    239	r = FLD_MOD(r, aud_dma->mode, 9, 9);
    240	r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
    241	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CTRL, r);
    242}
    243
    244int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable)
    245{
    246	REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 31, 31);
    247
    248	return 0;
    249}
    250
    251int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
    252{
    253	REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 30, 30);
    254
    255	return 0;
    256}
    257
    258int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
    259{
    260	struct resource *res;
    261
    262	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp");
    263	if (!res) {
    264		DSSERR("can't get WP mem resource\n");
    265		return -EINVAL;
    266	}
    267	wp->phys_base = res->start;
    268
    269	wp->base = devm_ioremap_resource(&pdev->dev, res);
    270	if (IS_ERR(wp->base)) {
    271		DSSERR("can't ioremap HDMI WP\n");
    272		return PTR_ERR(wp->base);
    273	}
    274
    275	return 0;
    276}
    277
    278phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp)
    279{
    280	return wp->phys_base + HDMI_WP_AUDIO_DATA;
    281}