root/drivers/media/pci/ivtv/ivtv-firmware.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. load_fw_direct
  2. ivtv_halt_firmware
  3. ivtv_firmware_versions
  4. ivtv_firmware_copy
  5. ivtv_search_mailbox
  6. ivtv_firmware_init
  7. ivtv_init_mpeg_decoder
  8. ivtv_firmware_restart
  9. ivtv_firmware_check

   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 
  40 static 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 
  45 retry:
  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 
  76 void 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 
 128 void 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 
 146 static 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 
 166 static 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 
 183 int 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 
 232 void 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 */
 267 static 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. */
 323 int 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 
 388 MODULE_FIRMWARE(CX2341X_FIRM_ENC_FILENAME);
 389 MODULE_FIRMWARE(CX2341X_FIRM_DEC_FILENAME);
 390 MODULE_FIRMWARE(IVTV_DECODE_INIT_MPEG_FILENAME);

/* [<][>][^][v][top][bottom][index][help] */