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

ivtv-firmware.c (11332B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3    ivtv firmware functions.
      4    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
      5    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
      6    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
      7
      8 */
      9
     10#include "ivtv-driver.h"
     11#include "ivtv-mailbox.h"
     12#include "ivtv-firmware.h"
     13#include "ivtv-yuv.h"
     14#include "ivtv-ioctl.h"
     15#include "ivtv-cards.h"
     16#include <linux/firmware.h>
     17#include <media/i2c/saa7127.h>
     18
     19#define IVTV_MASK_SPU_ENABLE		0xFFFFFFFE
     20#define IVTV_MASK_VPU_ENABLE15		0xFFFFFFF6
     21#define IVTV_MASK_VPU_ENABLE16		0xFFFFFFFB
     22#define IVTV_CMD_VDM_STOP		0x00000000
     23#define IVTV_CMD_AO_STOP		0x00000005
     24#define IVTV_CMD_APU_PING		0x00000000
     25#define IVTV_CMD_VPU_STOP15		0xFFFFFFFE
     26#define IVTV_CMD_VPU_STOP16		0xFFFFFFEE
     27#define IVTV_CMD_HW_BLOCKS_RST		0xFFFFFFFF
     28#define IVTV_CMD_SPU_STOP		0x00000001
     29#define IVTV_CMD_SDRAM_PRECHARGE_INIT	0x0000001A
     30#define IVTV_CMD_SDRAM_REFRESH_INIT	0x80000640
     31#define IVTV_SDRAM_SLEEPTIME		600
     32
     33#define IVTV_DECODE_INIT_MPEG_FILENAME	"v4l-cx2341x-init.mpg"
     34#define IVTV_DECODE_INIT_MPEG_SIZE	(152*1024)
     35
     36/* Encoder/decoder firmware sizes */
     37#define IVTV_FW_ENC_SIZE		(376836)
     38#define IVTV_FW_DEC_SIZE		(256*1024)
     39
     40static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
     41{
     42	const struct firmware *fw = NULL;
     43	int retries = 3;
     44
     45retry:
     46	if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
     47		int i;
     48		volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
     49		const u32 *src = (const u32 *)fw->data;
     50
     51		if (fw->size != size) {
     52			/* Due to race conditions in firmware loading (esp. with udev <0.95)
     53			   the wrong file was sometimes loaded. So we check filesizes to
     54			   see if at least the right-sized file was loaded. If not, then we
     55			   retry. */
     56			IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zu)\n", fn, size, fw->size);
     57			release_firmware(fw);
     58			retries--;
     59			goto retry;
     60		}
     61		for (i = 0; i < fw->size; i += 4) {
     62			/* no need for endianness conversion on the ppc */
     63			__raw_writel(*src, dst);
     64			dst++;
     65			src++;
     66		}
     67		IVTV_INFO("Loaded %s firmware (%zu bytes)\n", fn, fw->size);
     68		release_firmware(fw);
     69		return size;
     70	}
     71	IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size);
     72	IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n");
     73	return -ENOMEM;
     74}
     75
     76void ivtv_halt_firmware(struct ivtv *itv)
     77{
     78	IVTV_DEBUG_INFO("Preparing for firmware halt.\n");
     79	if (itv->has_cx23415 && itv->dec_mbox.mbox)
     80		ivtv_vapi(itv, CX2341X_DEC_HALT_FW, 0);
     81	if (itv->enc_mbox.mbox)
     82		ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0);
     83
     84	ivtv_msleep_timeout(10, 0);
     85	itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL;
     86
     87	IVTV_DEBUG_INFO("Stopping VDM\n");
     88	write_reg(IVTV_CMD_VDM_STOP, IVTV_REG_VDM);
     89
     90	IVTV_DEBUG_INFO("Stopping AO\n");
     91	write_reg(IVTV_CMD_AO_STOP, IVTV_REG_AO);
     92
     93	IVTV_DEBUG_INFO("pinging (?) APU\n");
     94	write_reg(IVTV_CMD_APU_PING, IVTV_REG_APU);
     95
     96	IVTV_DEBUG_INFO("Stopping VPU\n");
     97	if (!itv->has_cx23415)
     98		write_reg(IVTV_CMD_VPU_STOP16, IVTV_REG_VPU);
     99	else
    100		write_reg(IVTV_CMD_VPU_STOP15, IVTV_REG_VPU);
    101
    102	IVTV_DEBUG_INFO("Resetting Hw Blocks\n");
    103	write_reg(IVTV_CMD_HW_BLOCKS_RST, IVTV_REG_HW_BLOCKS);
    104
    105	IVTV_DEBUG_INFO("Stopping SPU\n");
    106	write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU);
    107
    108	ivtv_msleep_timeout(10, 0);
    109
    110	IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n");
    111	write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE);
    112
    113	IVTV_DEBUG_INFO("init Encoder SDRAM refresh to 1us\n");
    114	write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_ENC_SDRAM_REFRESH);
    115
    116	if (itv->has_cx23415) {
    117		IVTV_DEBUG_INFO("init Decoder SDRAM pre-charge\n");
    118		write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_DEC_SDRAM_PRECHARGE);
    119
    120		IVTV_DEBUG_INFO("init Decoder SDRAM refresh to 1us\n");
    121		write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH);
    122	}
    123
    124	IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME);
    125	ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0);
    126}
    127
    128void ivtv_firmware_versions(struct ivtv *itv)
    129{
    130	u32 data[CX2341X_MBOX_MAX_DATA];
    131
    132	/* Encoder */
    133	ivtv_vapi_result(itv, data, CX2341X_ENC_GET_VERSION, 0);
    134	IVTV_INFO("Encoder revision: 0x%08x\n", data[0]);
    135
    136	if (data[0] != 0x02060039)
    137		IVTV_WARN("Recommended firmware version is 0x02060039.\n");
    138
    139	if (itv->has_cx23415) {
    140		/* Decoder */
    141		ivtv_vapi_result(itv, data, CX2341X_DEC_GET_VERSION, 0);
    142		IVTV_INFO("Decoder revision: 0x%08x\n", data[0]);
    143	}
    144}
    145
    146static int ivtv_firmware_copy(struct ivtv *itv)
    147{
    148	IVTV_DEBUG_INFO("Loading encoder image\n");
    149	if (load_fw_direct(CX2341X_FIRM_ENC_FILENAME,
    150		   itv->enc_mem, itv, IVTV_FW_ENC_SIZE) != IVTV_FW_ENC_SIZE) {
    151		IVTV_DEBUG_WARN("failed loading encoder firmware\n");
    152		return -3;
    153	}
    154	if (!itv->has_cx23415)
    155		return 0;
    156
    157	IVTV_DEBUG_INFO("Loading decoder image\n");
    158	if (load_fw_direct(CX2341X_FIRM_DEC_FILENAME,
    159		   itv->dec_mem, itv, IVTV_FW_DEC_SIZE) != IVTV_FW_DEC_SIZE) {
    160		IVTV_DEBUG_WARN("failed loading decoder firmware\n");
    161		return -1;
    162	}
    163	return 0;
    164}
    165
    166static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile u8 __iomem *mem, u32 size)
    167{
    168	int i;
    169
    170	/* mailbox is preceded by a 16 byte 'magic cookie' starting at a 256-byte
    171	   address boundary */
    172	for (i = 0; i < size; i += 0x100) {
    173		if (readl(mem + i)      == 0x12345678 &&
    174		    readl(mem + i + 4)  == 0x34567812 &&
    175		    readl(mem + i + 8)  == 0x56781234 &&
    176		    readl(mem + i + 12) == 0x78123456) {
    177			return (volatile struct ivtv_mailbox __iomem *)(mem + i + 16);
    178		}
    179	}
    180	return NULL;
    181}
    182
    183int ivtv_firmware_init(struct ivtv *itv)
    184{
    185	int err;
    186
    187	ivtv_halt_firmware(itv);
    188
    189	/* load firmware */
    190	err = ivtv_firmware_copy(itv);
    191	if (err) {
    192		IVTV_DEBUG_WARN("Error %d loading firmware\n", err);
    193		return err;
    194	}
    195
    196	/* start firmware */
    197	write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU);
    198	ivtv_msleep_timeout(100, 0);
    199	if (itv->has_cx23415)
    200		write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU);
    201	else
    202		write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU);
    203	ivtv_msleep_timeout(100, 0);
    204
    205	/* find mailboxes and ping firmware */
    206	itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE);
    207	if (itv->enc_mbox.mbox == NULL)
    208		IVTV_ERR("Encoder mailbox not found\n");
    209	else if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0)) {
    210		IVTV_ERR("Encoder firmware dead!\n");
    211		itv->enc_mbox.mbox = NULL;
    212	}
    213	if (itv->enc_mbox.mbox == NULL)
    214		return -ENODEV;
    215
    216	if (!itv->has_cx23415)
    217		return 0;
    218
    219	itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
    220	if (itv->dec_mbox.mbox == NULL) {
    221		IVTV_ERR("Decoder mailbox not found\n");
    222	} else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
    223		IVTV_ERR("Decoder firmware dead!\n");
    224		itv->dec_mbox.mbox = NULL;
    225	} else {
    226		/* Firmware okay, so check yuv output filter table */
    227		ivtv_yuv_filter_check(itv);
    228	}
    229	return itv->dec_mbox.mbox ? 0 : -ENODEV;
    230}
    231
    232void ivtv_init_mpeg_decoder(struct ivtv *itv)
    233{
    234	u32 data[CX2341X_MBOX_MAX_DATA];
    235	long readbytes;
    236	volatile u8 __iomem *mem_offset;
    237
    238	data[0] = 0;
    239	data[1] = itv->cxhdl.width;	/* YUV source width */
    240	data[2] = itv->cxhdl.height;
    241	data[3] = itv->cxhdl.audio_properties;	/* Audio settings to use,
    242							   bitmap. see docs. */
    243	if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) {
    244		IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n");
    245		return;
    246	}
    247
    248	if (ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1) != 0) {
    249		IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
    250		return;
    251	}
    252	ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
    253	mem_offset = itv->dec_mem + data[1];
    254
    255	if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
    256		mem_offset, itv, IVTV_DECODE_INIT_MPEG_SIZE)) <= 0) {
    257		IVTV_DEBUG_WARN("failed to read mpeg decoder initialisation file %s\n",
    258				IVTV_DECODE_INIT_MPEG_FILENAME);
    259	} else {
    260		ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0);
    261		ivtv_msleep_timeout(100, 0);
    262	}
    263	ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
    264}
    265
    266/* Try to restart the card & restore previous settings */
    267static int ivtv_firmware_restart(struct ivtv *itv)
    268{
    269	int rc = 0;
    270	v4l2_std_id std;
    271
    272	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
    273		/* Display test image during restart */
    274		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
    275		    SAA7127_INPUT_TYPE_TEST_IMAGE,
    276		    itv->card->video_outputs[itv->active_output].video_output,
    277		    0);
    278
    279	mutex_lock(&itv->udma.lock);
    280
    281	rc = ivtv_firmware_init(itv);
    282	if (rc) {
    283		mutex_unlock(&itv->udma.lock);
    284		return rc;
    285	}
    286
    287	/* Allow settings to reload */
    288	ivtv_mailbox_cache_invalidate(itv);
    289
    290	/* Restore encoder video standard */
    291	std = itv->std;
    292	itv->std = 0;
    293	ivtv_s_std_enc(itv, std);
    294
    295	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
    296		ivtv_init_mpeg_decoder(itv);
    297
    298		/* Restore decoder video standard */
    299		std = itv->std_out;
    300		itv->std_out = 0;
    301		ivtv_s_std_dec(itv, std);
    302
    303		/* Restore framebuffer if active */
    304		if (itv->ivtvfb_restore)
    305			itv->ivtvfb_restore(itv);
    306
    307		/* Restore alpha settings */
    308		ivtv_set_osd_alpha(itv);
    309
    310		/* Restore normal output */
    311		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
    312		    SAA7127_INPUT_TYPE_NORMAL,
    313		    itv->card->video_outputs[itv->active_output].video_output,
    314		    0);
    315	}
    316
    317	mutex_unlock(&itv->udma.lock);
    318	return rc;
    319}
    320
    321/* Check firmware running state. The checks fall through
    322   allowing multiple failures to be logged. */
    323int ivtv_firmware_check(struct ivtv *itv, char *where)
    324{
    325	int res = 0;
    326
    327	/* Check encoder is still running */
    328	if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) {
    329		IVTV_WARN("Encoder has died : %s\n", where);
    330		res = -1;
    331	}
    332
    333	/* Also check audio. Only check if not in use & encoder is okay */
    334	if (!res && !atomic_read(&itv->capturing) &&
    335	    (!atomic_read(&itv->decoding) ||
    336	     (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV,
    337							     &itv->i_flags)))) {
    338
    339		if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) {
    340			IVTV_WARN("Audio has died (Encoder OK) : %s\n", where);
    341			res = -2;
    342		}
    343	}
    344
    345	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
    346		/* Second audio check. Skip if audio already failed */
    347		if (res != -2 && read_dec(0x100) != read_dec(0x104)) {
    348			/* Wait & try again to be certain. */
    349			ivtv_msleep_timeout(14, 0);
    350			if (read_dec(0x100) != read_dec(0x104)) {
    351				IVTV_WARN("Audio has died (Decoder) : %s\n",
    352					  where);
    353				res = -1;
    354			}
    355		}
    356
    357		/* Check decoder is still running */
    358		if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) {
    359			IVTV_WARN("Decoder has died : %s\n", where);
    360			res = -1;
    361		}
    362	}
    363
    364	/* If something failed & currently idle, try to reload */
    365	if (res && !atomic_read(&itv->capturing) &&
    366						!atomic_read(&itv->decoding)) {
    367		IVTV_INFO("Detected in %s that firmware had failed - Reloading\n",
    368			  where);
    369		res = ivtv_firmware_restart(itv);
    370		/*
    371		 * Even if restarted ok, still signal a problem had occurred.
    372		 * The caller can come through this function again to check
    373		 * if things are really ok after the restart.
    374		 */
    375		if (!res) {
    376			IVTV_INFO("Firmware restart okay\n");
    377			res = -EAGAIN;
    378		} else {
    379			IVTV_INFO("Firmware restart failed\n");
    380		}
    381	} else if (res) {
    382		res = -EIO;
    383	}
    384
    385	return res;
    386}
    387
    388MODULE_FIRMWARE(CX2341X_FIRM_ENC_FILENAME);
    389MODULE_FIRMWARE(CX2341X_FIRM_DEC_FILENAME);
    390MODULE_FIRMWARE(IVTV_DECODE_INIT_MPEG_FILENAME);