saa7164-fw.c (15862B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Driver for the NXP SAA7164 PCIe bridge 4 * 5 * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com> 6 */ 7 8#include <linux/firmware.h> 9#include <linux/slab.h> 10 11#include "saa7164.h" 12 13#define SAA7164_REV2_FIRMWARE "NXP7164-2010-03-10.1.fw" 14#define SAA7164_REV2_FIRMWARE_SIZE 4019072 15 16#define SAA7164_REV3_FIRMWARE "NXP7164-2010-03-10.1.fw" 17#define SAA7164_REV3_FIRMWARE_SIZE 4019072 18 19struct fw_header { 20 u32 firmwaresize; 21 u32 bslsize; 22 u32 reserved; 23 u32 version; 24}; 25 26static int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg) 27{ 28 u32 timeout = SAA_DEVICE_TIMEOUT; 29 while ((saa7164_readl(reg) & 0x01) == 0) { 30 timeout -= 10; 31 if (timeout == 0) { 32 printk(KERN_ERR "%s() timeout (no d/l ack)\n", 33 __func__); 34 return -EBUSY; 35 } 36 msleep(100); 37 } 38 39 return 0; 40} 41 42static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg) 43{ 44 u32 timeout = SAA_DEVICE_TIMEOUT; 45 while (saa7164_readl(reg) & 0x01) { 46 timeout -= 10; 47 if (timeout == 0) { 48 printk(KERN_ERR "%s() timeout (no d/l clr)\n", 49 __func__); 50 return -EBUSY; 51 } 52 msleep(100); 53 } 54 55 return 0; 56} 57 58/* TODO: move dlflags into dev-> and change to write/readl/b */ 59/* TODO: Excessive levels of debug */ 60static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, 61 u32 dlflags, u8 __iomem *dst, u32 dstsize) 62{ 63 u32 reg, timeout, offset; 64 u8 *srcbuf = NULL; 65 int ret; 66 67 u32 dlflag = dlflags; 68 u32 dlflag_ack = dlflag + 4; 69 u32 drflag = dlflag_ack + 4; 70 u32 drflag_ack = drflag + 4; 71 u32 bleflag = drflag_ack + 4; 72 73 dprintk(DBGLVL_FW, 74 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n", 75 __func__, src, srcsize, dlflags, dst, dstsize); 76 77 if ((src == NULL) || (dst == NULL)) { 78 ret = -EIO; 79 goto out; 80 } 81 82 srcbuf = kzalloc(4 * 1048576, GFP_KERNEL); 83 if (NULL == srcbuf) { 84 ret = -ENOMEM; 85 goto out; 86 } 87 88 if (srcsize > (4*1048576)) { 89 ret = -ENOMEM; 90 goto out; 91 } 92 93 memcpy(srcbuf, src, srcsize); 94 95 dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag); 96 dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack); 97 dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag); 98 dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack); 99 dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag); 100 101 reg = saa7164_readl(dlflag); 102 dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg); 103 if (reg == 1) 104 dprintk(DBGLVL_FW, 105 "%s() Download flag already set, please reboot\n", 106 __func__); 107 108 /* Indicate download start */ 109 saa7164_writel(dlflag, 1); 110 ret = saa7164_dl_wait_ack(dev, dlflag_ack); 111 if (ret < 0) 112 goto out; 113 114 /* Ack download start, then wait for wait */ 115 saa7164_writel(dlflag, 0); 116 ret = saa7164_dl_wait_clr(dev, dlflag_ack); 117 if (ret < 0) 118 goto out; 119 120 /* Deal with the raw firmware, in the appropriate chunk size */ 121 for (offset = 0; srcsize > dstsize; 122 srcsize -= dstsize, offset += dstsize) { 123 124 dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize); 125 memcpy_toio(dst, srcbuf + offset, dstsize); 126 127 /* Flag the data as ready */ 128 saa7164_writel(drflag, 1); 129 ret = saa7164_dl_wait_ack(dev, drflag_ack); 130 if (ret < 0) 131 goto out; 132 133 /* Wait for indication data was received */ 134 saa7164_writel(drflag, 0); 135 ret = saa7164_dl_wait_clr(dev, drflag_ack); 136 if (ret < 0) 137 goto out; 138 139 } 140 141 dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize); 142 /* Write last block to the device */ 143 memcpy_toio(dst, srcbuf+offset, srcsize); 144 145 /* Flag the data as ready */ 146 saa7164_writel(drflag, 1); 147 ret = saa7164_dl_wait_ack(dev, drflag_ack); 148 if (ret < 0) 149 goto out; 150 151 saa7164_writel(drflag, 0); 152 timeout = 0; 153 while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) { 154 if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) { 155 printk(KERN_ERR "%s() image corrupt\n", __func__); 156 ret = -EBUSY; 157 goto out; 158 } 159 160 if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) { 161 printk(KERN_ERR "%s() device memory corrupt\n", 162 __func__); 163 ret = -EBUSY; 164 goto out; 165 } 166 167 msleep(10); /* Checkpatch throws a < 20ms warning */ 168 if (timeout++ > 60) 169 break; 170 } 171 172 printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__); 173 174 ret = saa7164_dl_wait_clr(dev, drflag_ack); 175 if (ret < 0) 176 goto out; 177 178 printk(KERN_INFO "%s() Image booted successfully.\n", __func__); 179 ret = 0; 180 181out: 182 kfree(srcbuf); 183 return ret; 184} 185 186/* TODO: Excessive debug */ 187/* Load the firmware. Optionally it can be in ROM or newer versions 188 * can be on disk, saving the expense of the ROM hardware. */ 189int saa7164_downloadfirmware(struct saa7164_dev *dev) 190{ 191 /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */ 192 u32 tmp, filesize, version, err_flags, first_timeout, fwlength; 193 u32 second_timeout, updatebootloader = 1, bootloadersize = 0; 194 const struct firmware *fw = NULL; 195 struct fw_header *hdr, *boothdr = NULL, *fwhdr; 196 u32 bootloaderversion = 0, fwloadersize; 197 u8 *bootloaderoffset = NULL, *fwloaderoffset; 198 char *fwname; 199 int ret; 200 201 dprintk(DBGLVL_FW, "%s()\n", __func__); 202 203 if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) { 204 fwname = SAA7164_REV2_FIRMWARE; 205 fwlength = SAA7164_REV2_FIRMWARE_SIZE; 206 } else { 207 fwname = SAA7164_REV3_FIRMWARE; 208 fwlength = SAA7164_REV3_FIRMWARE_SIZE; 209 } 210 211 version = saa7164_getcurrentfirmwareversion(dev); 212 213 if (version == 0x00) { 214 215 second_timeout = 100; 216 first_timeout = 100; 217 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS); 218 dprintk(DBGLVL_FW, "%s() err_flags = %x\n", 219 __func__, err_flags); 220 221 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { 222 dprintk(DBGLVL_FW, "%s() err_flags = %x\n", 223 __func__, err_flags); 224 msleep(10); /* Checkpatch throws a < 20ms warning */ 225 226 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { 227 printk(KERN_ERR "%s() firmware corrupt\n", 228 __func__); 229 break; 230 } 231 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) { 232 printk(KERN_ERR "%s() device memory corrupt\n", 233 __func__); 234 break; 235 } 236 if (err_flags & SAA_DEVICE_NO_IMAGE) { 237 printk(KERN_ERR "%s() no first image\n", 238 __func__); 239 break; 240 } 241 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) { 242 first_timeout -= 10; 243 if (first_timeout == 0) { 244 printk(KERN_ERR 245 "%s() no first image\n", 246 __func__); 247 break; 248 } 249 } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) { 250 second_timeout -= 10; 251 if (second_timeout == 0) { 252 printk(KERN_ERR 253 "%s() FW load time exceeded\n", 254 __func__); 255 break; 256 } 257 } else { 258 second_timeout -= 10; 259 if (second_timeout == 0) { 260 printk(KERN_ERR 261 "%s() Unknown bootloader flags 0x%x\n", 262 __func__, err_flags); 263 break; 264 } 265 } 266 267 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS); 268 } /* While != Booting */ 269 270 if (err_flags == SAA_DEVICE_IMAGE_BOOTING) { 271 dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n", 272 __func__); 273 first_timeout = SAA_DEVICE_TIMEOUT; 274 second_timeout = 60 * SAA_DEVICE_TIMEOUT; 275 second_timeout = 100; 276 277 err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS); 278 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", 279 __func__, err_flags); 280 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { 281 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", 282 __func__, err_flags); 283 msleep(10); /* Checkpatch throws a < 20ms warning */ 284 285 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { 286 printk(KERN_ERR 287 "%s() firmware corrupt\n", 288 __func__); 289 break; 290 } 291 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) { 292 printk(KERN_ERR 293 "%s() device memory corrupt\n", 294 __func__); 295 break; 296 } 297 if (err_flags & SAA_DEVICE_NO_IMAGE) { 298 printk(KERN_ERR "%s() no second image\n", 299 __func__); 300 break; 301 } 302 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) { 303 first_timeout -= 10; 304 if (first_timeout == 0) { 305 printk(KERN_ERR 306 "%s() no second image\n", 307 __func__); 308 break; 309 } 310 } else if (err_flags & 311 SAA_DEVICE_IMAGE_LOADING) { 312 second_timeout -= 10; 313 if (second_timeout == 0) { 314 printk(KERN_ERR 315 "%s() FW load time exceeded\n", 316 __func__); 317 break; 318 } 319 } else { 320 second_timeout -= 10; 321 if (second_timeout == 0) { 322 printk(KERN_ERR 323 "%s() Unknown bootloader flags 0x%x\n", 324 __func__, err_flags); 325 break; 326 } 327 } 328 329 err_flags = 330 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS); 331 } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */ 332 333 dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n", 334 __func__, 335 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS), 336 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS)); 337 338 } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */ 339 340 /* It's possible for both firmwares to have booted, 341 * but that doesn't mean they've finished booting yet. 342 */ 343 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == 344 SAA_DEVICE_IMAGE_BOOTING) && 345 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) == 346 SAA_DEVICE_IMAGE_BOOTING)) { 347 348 349 dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n", 350 __func__); 351 352 first_timeout = SAA_DEVICE_TIMEOUT; 353 while (first_timeout) { 354 msleep(10); /* Checkpatch throws a < 20ms warning */ 355 356 version = 357 saa7164_getcurrentfirmwareversion(dev); 358 if (version) { 359 dprintk(DBGLVL_FW, 360 "%s() All f/w loaded successfully\n", 361 __func__); 362 break; 363 } else { 364 first_timeout -= 10; 365 if (first_timeout == 0) { 366 printk(KERN_ERR 367 "%s() FW did not boot\n", 368 __func__); 369 break; 370 } 371 } 372 } 373 } 374 version = saa7164_getcurrentfirmwareversion(dev); 375 } /* version == 0 */ 376 377 /* Has the firmware really booted? */ 378 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == 379 SAA_DEVICE_IMAGE_BOOTING) && 380 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) == 381 SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) { 382 383 printk(KERN_ERR 384 "%s() The firmware hung, probably bad firmware\n", 385 __func__); 386 387 /* Tell the second stage loader we have a deadlock */ 388 saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET, 389 SAA_DEVICE_DEADLOCK_DETECTED); 390 391 saa7164_getfirmwarestatus(dev); 392 393 return -ENOMEM; 394 } 395 396 dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n", 397 (version & 0x0000fc00) >> 10, 398 (version & 0x000003e0) >> 5, 399 (version & 0x0000001f), 400 (version & 0xffff0000) >> 16); 401 402 /* Load the firmware from the disk if required */ 403 if (version == 0) { 404 405 printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n", 406 __func__, fwname); 407 408 ret = request_firmware(&fw, fwname, &dev->pci->dev); 409 if (ret) { 410 printk(KERN_ERR "%s() Upload failed. (file not found?)\n", 411 __func__); 412 return -ENOMEM; 413 } 414 415 printk(KERN_INFO "%s() firmware read %zu bytes.\n", 416 __func__, fw->size); 417 418 if (fw->size != fwlength) { 419 printk(KERN_ERR "saa7164: firmware incorrect size %zu != %u\n", 420 fw->size, fwlength); 421 ret = -ENOMEM; 422 goto out; 423 } 424 425 printk(KERN_INFO "%s() firmware loaded.\n", __func__); 426 427 hdr = (struct fw_header *)fw->data; 428 printk(KERN_INFO "Firmware file header part 1:\n"); 429 printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize); 430 printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize); 431 printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved); 432 printk(KERN_INFO " .Version = 0x%x\n", hdr->version); 433 434 /* Retrieve bootloader if reqd */ 435 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) 436 /* Second bootloader in the firmware file */ 437 filesize = hdr->reserved * 16; 438 else 439 filesize = (hdr->firmwaresize + hdr->bslsize) * 440 16 + sizeof(struct fw_header); 441 442 printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n", 443 __func__, filesize); 444 445 /* Get bootloader (if reqd) and firmware header */ 446 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) { 447 /* Second boot loader is required */ 448 449 /* Get the loader header */ 450 boothdr = (struct fw_header *)(fw->data + 451 sizeof(struct fw_header)); 452 453 bootloaderversion = 454 saa7164_readl(SAA_DEVICE_2ND_VERSION); 455 dprintk(DBGLVL_FW, "Onboard BootLoader:\n"); 456 dprintk(DBGLVL_FW, "->Flag 0x%x\n", 457 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS)); 458 dprintk(DBGLVL_FW, "->Ack 0x%x\n", 459 saa7164_readl(SAA_DATAREADY_FLAG_ACK)); 460 dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version); 461 dprintk(DBGLVL_FW, "->Loader Version 0x%x\n", 462 bootloaderversion); 463 464 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) == 465 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK) 466 == 0x00) && (version == 0x00)) { 467 468 dprintk(DBGLVL_FW, "BootLoader version in rom %d.%d.%d.%d\n", 469 (bootloaderversion & 0x0000fc00) >> 10, 470 (bootloaderversion & 0x000003e0) >> 5, 471 (bootloaderversion & 0x0000001f), 472 (bootloaderversion & 0xffff0000) >> 16 473 ); 474 dprintk(DBGLVL_FW, "BootLoader version in file %d.%d.%d.%d\n", 475 (boothdr->version & 0x0000fc00) >> 10, 476 (boothdr->version & 0x000003e0) >> 5, 477 (boothdr->version & 0x0000001f), 478 (boothdr->version & 0xffff0000) >> 16 479 ); 480 481 if (bootloaderversion == boothdr->version) 482 updatebootloader = 0; 483 } 484 485 /* Calculate offset to firmware header */ 486 tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 + 487 (sizeof(struct fw_header) + 488 sizeof(struct fw_header)); 489 490 fwhdr = (struct fw_header *)(fw->data+tmp); 491 } else { 492 /* No second boot loader */ 493 fwhdr = hdr; 494 } 495 496 dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n", 497 (fwhdr->version & 0x0000fc00) >> 10, 498 (fwhdr->version & 0x000003e0) >> 5, 499 (fwhdr->version & 0x0000001f), 500 (fwhdr->version & 0xffff0000) >> 16 501 ); 502 503 if (version == fwhdr->version) { 504 /* No download, firmware already on board */ 505 ret = 0; 506 goto out; 507 } 508 509 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) { 510 if (updatebootloader) { 511 /* Get ready to upload the bootloader */ 512 bootloadersize = (boothdr->firmwaresize + 513 boothdr->bslsize) * 16 + 514 sizeof(struct fw_header); 515 516 bootloaderoffset = (u8 *)(fw->data + 517 sizeof(struct fw_header)); 518 519 dprintk(DBGLVL_FW, "bootloader d/l starts.\n"); 520 printk(KERN_INFO "%s() FirmwareSize = 0x%x\n", 521 __func__, boothdr->firmwaresize); 522 printk(KERN_INFO "%s() BSLSize = 0x%x\n", 523 __func__, boothdr->bslsize); 524 printk(KERN_INFO "%s() Reserved = 0x%x\n", 525 __func__, boothdr->reserved); 526 printk(KERN_INFO "%s() Version = 0x%x\n", 527 __func__, boothdr->version); 528 ret = saa7164_downloadimage( 529 dev, 530 bootloaderoffset, 531 bootloadersize, 532 SAA_DOWNLOAD_FLAGS, 533 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET, 534 SAA_DEVICE_BUFFERBLOCKSIZE); 535 if (ret < 0) { 536 printk(KERN_ERR 537 "bootloader d/l has failed\n"); 538 goto out; 539 } 540 dprintk(DBGLVL_FW, 541 "bootloader download complete.\n"); 542 543 } 544 545 printk(KERN_ERR "starting firmware download(2)\n"); 546 bootloadersize = (boothdr->firmwaresize + 547 boothdr->bslsize) * 16 + 548 sizeof(struct fw_header); 549 550 bootloaderoffset = 551 (u8 *)(fw->data + sizeof(struct fw_header)); 552 553 fwloaderoffset = bootloaderoffset + bootloadersize; 554 555 /* TODO: fix this bounds overrun here with old f/ws */ 556 fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) * 557 16 + sizeof(struct fw_header); 558 559 ret = saa7164_downloadimage( 560 dev, 561 fwloaderoffset, 562 fwloadersize, 563 SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET, 564 dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET, 565 SAA_DEVICE_2ND_BUFFERBLOCKSIZE); 566 if (ret < 0) { 567 printk(KERN_ERR "firmware download failed\n"); 568 goto out; 569 } 570 printk(KERN_ERR "firmware download complete.\n"); 571 572 } else { 573 574 /* No bootloader update reqd, download firmware only */ 575 printk(KERN_ERR "starting firmware download(3)\n"); 576 577 ret = saa7164_downloadimage( 578 dev, 579 (u8 *)fw->data, 580 fw->size, 581 SAA_DOWNLOAD_FLAGS, 582 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET, 583 SAA_DEVICE_BUFFERBLOCKSIZE); 584 if (ret < 0) { 585 printk(KERN_ERR "firmware download failed\n"); 586 goto out; 587 } 588 printk(KERN_ERR "firmware download complete.\n"); 589 } 590 } 591 592 dev->firmwareloaded = 1; 593 ret = 0; 594 595out: 596 release_firmware(fw); 597 return ret; 598}