1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * driver for the SAA7146 based AV110 cards 4 * - av7110 low level hardware access and firmware interface 5 * 6 * Copyright (C) 1999-2002 Ralph Metzler 7 * & Marcus Metzler for convergence integrated media GmbH 8 * 9 * originally based on code by: 10 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> 11 * 12 * the project's page is at https://linuxtv.org 13 */ 14 15 /* for debugging ARM communication: */ 16 //#define COM_DEBUG 17 18 #include <linux/types.h> 19 #include <linux/kernel.h> 20 #include <linux/string.h> 21 #include <linux/delay.h> 22 #include <linux/fs.h> 23 24 #include "av7110.h" 25 #include "av7110_hw.h" 26 27 #define _NOHANDSHAKE 28 29 /* 30 * Max transfer size done by av7110_fw_cmd() 31 * 32 * The maximum size passed to this function is 6 bytes. The buffer also 33 * uses two additional ones for type and size. So, 8 bytes is enough. 34 */ 35 #define MAX_XFER_SIZE 8 36 37 /**************************************************************************** 38 * DEBI functions 39 ****************************************************************************/ 40 41 /* This DEBI code is based on the Stradis driver 42 * by Nathan Laredo <laredo@gnu.org> 43 */ 44 45 int av7110_debiwrite(struct av7110 *av7110, u32 config, 46 int addr, u32 val, unsigned int count) 47 { 48 struct saa7146_dev *dev = av7110->dev; 49 50 if (count > 32764) { 51 pr_err("%s(): invalid count %d\n", __func__, count); 52 return -1; 53 } 54 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { 55 pr_err("%s(): wait_for_debi_done failed\n", __func__); 56 return -1; 57 } 58 saa7146_write(dev, DEBI_CONFIG, config); 59 if (count <= 4) /* immediate transfer */ 60 saa7146_write(dev, DEBI_AD, val); 61 else /* block transfer */ 62 saa7146_write(dev, DEBI_AD, av7110->debi_bus); 63 saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff)); 64 saa7146_write(dev, MC2, (2 << 16) | 2); 65 return 0; 66 } 67 68 u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int count) 69 { 70 struct saa7146_dev *dev = av7110->dev; 71 u32 result = 0; 72 73 if (count > 32764) { 74 pr_err("%s(): invalid count %d\n", __func__, count); 75 return 0; 76 } 77 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { 78 pr_err("%s(): wait_for_debi_done #1 failed\n", __func__); 79 return 0; 80 } 81 saa7146_write(dev, DEBI_AD, av7110->debi_bus); 82 saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); 83 84 saa7146_write(dev, DEBI_CONFIG, config); 85 saa7146_write(dev, MC2, (2 << 16) | 2); 86 if (count > 4) 87 return count; 88 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { 89 pr_err("%s(): wait_for_debi_done #2 failed\n", __func__); 90 return 0; 91 } 92 93 result = saa7146_read(dev, DEBI_AD); 94 result &= (0xffffffffUL >> ((4 - count) * 8)); 95 return result; 96 } 97 98 /* av7110 ARM core boot stuff */ 99 #if 0 100 void av7110_reset_arm(struct av7110 *av7110) 101 { 102 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); 103 104 /* Disable DEBI and GPIO irq */ 105 SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03); 106 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); 107 108 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); 109 msleep(30); /* the firmware needs some time to initialize */ 110 111 ARM_ResetMailBox(av7110); 112 113 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); 114 SAA7146_IER_ENABLE(av7110->dev, MASK_03); 115 116 av7110->arm_ready = 1; 117 dprintk(1, "reset ARM\n"); 118 } 119 #endif /* 0 */ 120 121 static int waitdebi(struct av7110 *av7110, int adr, int state) 122 { 123 int k; 124 125 dprintk(4, "%p\n", av7110); 126 127 for (k = 0; k < 100; k++) { 128 if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) 129 return 0; 130 udelay(5); 131 } 132 return -ETIMEDOUT; 133 } 134 135 static int load_dram(struct av7110 *av7110, u32 *data, int len) 136 { 137 int i; 138 int blocks, rest; 139 u32 base, bootblock = AV7110_BOOT_BLOCK; 140 141 dprintk(4, "%p\n", av7110); 142 143 blocks = len / AV7110_BOOT_MAX_SIZE; 144 rest = len % AV7110_BOOT_MAX_SIZE; 145 base = DRAM_START_CODE; 146 147 for (i = 0; i < blocks; i++) { 148 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 149 pr_err("%s(): timeout at block %d\n", __func__, i); 150 return -ETIMEDOUT; 151 } 152 dprintk(4, "writing DRAM block %d\n", i); 153 mwdebi(av7110, DEBISWAB, bootblock, 154 ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE); 155 bootblock ^= 0x1400; 156 iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); 157 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2); 158 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); 159 base += AV7110_BOOT_MAX_SIZE; 160 } 161 162 if (rest > 0) { 163 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 164 pr_err("%s(): timeout at last block\n", __func__); 165 return -ETIMEDOUT; 166 } 167 if (rest > 4) 168 mwdebi(av7110, DEBISWAB, bootblock, 169 ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest); 170 else 171 mwdebi(av7110, DEBISWAB, bootblock, 172 ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4); 173 174 iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); 175 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2); 176 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); 177 } 178 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 179 pr_err("%s(): timeout after last block\n", __func__); 180 return -ETIMEDOUT; 181 } 182 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2); 183 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); 184 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) { 185 pr_err("%s(): final handshake timeout\n", __func__); 186 return -ETIMEDOUT; 187 } 188 return 0; 189 } 190 191 /* we cannot write av7110 DRAM directly, so load a bootloader into 192 * the DPRAM which implements a simple boot protocol 193 */ 194 int av7110_bootarm(struct av7110 *av7110) 195 { 196 const struct firmware *fw; 197 const char *fw_name = "av7110/bootcode.bin"; 198 struct saa7146_dev *dev = av7110->dev; 199 u32 ret; 200 int i; 201 202 dprintk(4, "%p\n", av7110); 203 204 av7110->arm_ready = 0; 205 206 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); 207 208 /* Disable DEBI and GPIO irq */ 209 SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19); 210 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); 211 212 /* enable DEBI */ 213 saa7146_write(av7110->dev, MC1, 0x08800880); 214 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); 215 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); 216 217 /* test DEBI */ 218 iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); 219 /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */ 220 iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); 221 222 ret = irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4); 223 if (ret != 0x10325476) { 224 pr_err("debi test in %s() failed: %08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", 225 __func__, ret, 0x10325476); 226 return -1; 227 } 228 for (i = 0; i < 8192; i += 4) 229 iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4); 230 dprintk(2, "debi test OK\n"); 231 232 /* boot */ 233 dprintk(1, "load boot code\n"); 234 saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO); 235 //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT); 236 //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); 237 238 ret = request_firmware(&fw, fw_name, &dev->pci->dev); 239 if (ret) { 240 pr_err("Failed to load firmware \"%s\"\n", fw_name); 241 return ret; 242 } 243 244 mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); 245 release_firmware(fw); 246 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); 247 248 if (saa7146_wait_for_debi_done(av7110->dev, 1)) { 249 pr_err("%s(): saa7146_wait_for_debi_done() timed out\n", __func__); 250 return -ETIMEDOUT; 251 } 252 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); 253 mdelay(1); 254 255 dprintk(1, "load dram code\n"); 256 if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) { 257 pr_err("%s(): load_dram() failed\n", __func__); 258 return -1; 259 } 260 261 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); 262 mdelay(1); 263 264 dprintk(1, "load dpram code\n"); 265 mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram); 266 267 if (saa7146_wait_for_debi_done(av7110->dev, 1)) { 268 pr_err("%s(): saa7146_wait_for_debi_done() timed out after loading DRAM\n", __func__); 269 return -ETIMEDOUT; 270 } 271 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); 272 msleep(30); /* the firmware needs some time to initialize */ 273 274 //ARM_ClearIrq(av7110); 275 ARM_ResetMailBox(av7110); 276 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); 277 SAA7146_IER_ENABLE(av7110->dev, MASK_03); 278 279 av7110->arm_errors = 0; 280 av7110->arm_ready = 1; 281 return 0; 282 } 283 MODULE_FIRMWARE("av7110/bootcode.bin"); 284 285 /**************************************************************************** 286 * DEBI command polling 287 ****************************************************************************/ 288 289 int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) 290 { 291 unsigned long start; 292 u32 stat; 293 int err; 294 295 if (FW_VERSION(av7110->arm_app) <= 0x261c) { 296 /* not supported by old firmware */ 297 msleep(50); 298 return 0; 299 } 300 301 /* new firmware */ 302 start = jiffies; 303 for (;;) { 304 err = time_after(jiffies, start + ARM_WAIT_FREE); 305 if (mutex_lock_interruptible(&av7110->dcomlock)) 306 return -ERESTARTSYS; 307 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 308 mutex_unlock(&av7110->dcomlock); 309 if ((stat & flags) == 0) 310 break; 311 if (err) { 312 pr_err("%s(): timeout waiting for MSGSTATE %04x\n", __func__, stat & flags); 313 return -ETIMEDOUT; 314 } 315 usleep_range(1000, 2000); 316 } 317 return 0; 318 } 319 320 static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length) 321 { 322 int i; 323 unsigned long start; 324 char *type = NULL; 325 u16 flags[2] = {0, 0}; 326 u32 stat; 327 int err; 328 329 // dprintk(4, "%p\n", av7110); 330 331 if (!av7110->arm_ready) { 332 dprintk(1, "arm not ready.\n"); 333 return -ENXIO; 334 } 335 336 start = jiffies; 337 while (1) { 338 err = time_after(jiffies, start + ARM_WAIT_FREE); 339 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) 340 break; 341 if (err) { 342 pr_err("%s(): timeout waiting for COMMAND idle\n", __func__); 343 av7110->arm_errors++; 344 return -ETIMEDOUT; 345 } 346 usleep_range(1000, 2000); 347 } 348 349 if (FW_VERSION(av7110->arm_app) <= 0x261f) 350 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2); 351 352 #ifndef _NOHANDSHAKE 353 start = jiffies; 354 while (1) { 355 err = time_after(jiffies, start + ARM_WAIT_SHAKE); 356 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) 357 break; 358 if (err) { 359 pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__); 360 return -ETIMEDOUT; 361 } 362 usleep_range(1000, 2000); 363 } 364 #endif 365 366 switch ((buf[0] >> 8) & 0xff) { 367 case COMTYPE_PIDFILTER: 368 case COMTYPE_ENCODER: 369 case COMTYPE_REC_PLAY: 370 case COMTYPE_MPEGDECODER: 371 type = "MSG"; 372 flags[0] = GPMQOver; 373 flags[1] = GPMQFull; 374 break; 375 case COMTYPE_OSD: 376 type = "OSD"; 377 flags[0] = OSDQOver; 378 flags[1] = OSDQFull; 379 break; 380 case COMTYPE_MISC: 381 if (FW_VERSION(av7110->arm_app) >= 0x261d) { 382 type = "MSG"; 383 flags[0] = GPMQOver; 384 flags[1] = GPMQBusy; 385 } 386 break; 387 default: 388 break; 389 } 390 391 if (type) { 392 /* non-immediate COMMAND type */ 393 start = jiffies; 394 for (;;) { 395 err = time_after(jiffies, start + ARM_WAIT_FREE); 396 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 397 if (stat & flags[0]) { 398 pr_err("%s(): %s QUEUE overflow\n", __func__, type); 399 return -1; 400 } 401 if ((stat & flags[1]) == 0) 402 break; 403 if (err) { 404 pr_err("%s(): timeout waiting on busy %s QUEUE\n", __func__, type); 405 av7110->arm_errors++; 406 return -ETIMEDOUT; 407 } 408 usleep_range(1000, 2000); 409 } 410 } 411 412 for (i = 2; i < length; i++) 413 wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32)buf[i], 2); 414 415 if (length) 416 wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32)buf[1], 2); 417 else 418 wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2); 419 420 wdebi(av7110, DEBINOSWAP, COMMAND, (u32)buf[0], 2); 421 422 if (FW_VERSION(av7110->arm_app) <= 0x261f) 423 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2); 424 425 #ifdef COM_DEBUG 426 start = jiffies; 427 while (1) { 428 err = time_after(jiffies, start + ARM_WAIT_FREE); 429 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) 430 break; 431 if (err) { 432 pr_err("%s(): timeout waiting for COMMAND %d to complete\n", 433 __func__, (buf[0] >> 8) & 0xff); 434 return -ETIMEDOUT; 435 } 436 usleep_range(1000, 2000); 437 } 438 439 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 440 if (stat & GPMQOver) { 441 pr_err("%s(): GPMQOver\n", __func__); 442 return -ENOSPC; 443 } else if (stat & OSDQOver) { 444 pr_err("%s(): OSDQOver\n", __func__); 445 return -ENOSPC; 446 } 447 #endif 448 449 return 0; 450 } 451 452 static int av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length) 453 { 454 int ret; 455 456 // dprintk(4, "%p\n", av7110); 457 458 if (!av7110->arm_ready) { 459 dprintk(1, "arm not ready.\n"); 460 return -1; 461 } 462 if (mutex_lock_interruptible(&av7110->dcomlock)) 463 return -ERESTARTSYS; 464 465 ret = __av7110_send_fw_cmd(av7110, buf, length); 466 mutex_unlock(&av7110->dcomlock); 467 if (ret && ret != -ERESTARTSYS) 468 pr_err("%s(): error %d\n", __func__, ret); 469 return ret; 470 } 471 472 int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...) 473 { 474 va_list args; 475 u16 buf[MAX_XFER_SIZE]; 476 int i, ret; 477 478 // dprintk(4, "%p\n", av7110); 479 480 if (2 + num > ARRAY_SIZE(buf)) { 481 pr_warn("%s(): len=%d is too big!\n", __func__, num); 482 return -EINVAL; 483 } 484 485 buf[0] = ((type << 8) | com); 486 buf[1] = num; 487 488 if (num) { 489 va_start(args, num); 490 for (i = 0; i < num; i++) 491 buf[i + 2] = va_arg(args, u32); 492 va_end(args); 493 } 494 495 ret = av7110_send_fw_cmd(av7110, buf, num + 2); 496 if (ret && ret != -ERESTARTSYS) 497 pr_err("%s(): error %d\n", __func__, ret); 498 return ret; 499 } 500 501 #if 0 502 int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) 503 { 504 int i, ret; 505 u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom), 506 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 507 508 dprintk(4, "%p\n", av7110); 509 510 for (i = 0; i < len && i < 32; i++) { 511 if (i % 2 == 0) 512 cmd[(i / 2) + 2] = (u16)(buf[i]) << 8; 513 else 514 cmd[(i / 2) + 2] |= buf[i]; 515 } 516 517 ret = av7110_send_fw_cmd(av7110, cmd, 18); 518 if (ret && ret != -ERESTARTSYS) 519 pr_err("%s(): error %d\n", __func__, ret); 520 return ret; 521 } 522 #endif /* 0 */ 523 524 int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, 525 int request_buf_len, u16 *reply_buf, int reply_buf_len) 526 { 527 int err; 528 s16 i; 529 unsigned long start; 530 #ifdef COM_DEBUG 531 u32 stat; 532 #endif 533 534 dprintk(4, "%p\n", av7110); 535 536 if (!av7110->arm_ready) { 537 dprintk(1, "arm not ready.\n"); 538 return -1; 539 } 540 541 if (mutex_lock_interruptible(&av7110->dcomlock)) 542 return -ERESTARTSYS; 543 544 err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len); 545 if (err < 0) { 546 mutex_unlock(&av7110->dcomlock); 547 pr_err("%s(): error %d\n", __func__, err); 548 return err; 549 } 550 551 start = jiffies; 552 while (1) { 553 err = time_after(jiffies, start + ARM_WAIT_FREE); 554 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) 555 break; 556 if (err) { 557 pr_err("%s(): timeout waiting for COMMAND to complete\n", __func__); 558 mutex_unlock(&av7110->dcomlock); 559 return -ETIMEDOUT; 560 } 561 #ifdef _NOHANDSHAKE 562 usleep_range(1000, 2000); 563 #endif 564 } 565 566 #ifndef _NOHANDSHAKE 567 start = jiffies; 568 while (1) { 569 err = time_after(jiffies, start + ARM_WAIT_SHAKE); 570 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) 571 break; 572 if (err) { 573 pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__); 574 mutex_unlock(&av7110->dcomlock); 575 return -ETIMEDOUT; 576 } 577 usleep_range(1000, 2000); 578 } 579 #endif 580 581 #ifdef COM_DEBUG 582 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 583 if (stat & GPMQOver) { 584 pr_err("%s(): GPMQOver\n", __func__); 585 mutex_unlock(&av7110->dcomlock); 586 return -1; 587 } else if (stat & OSDQOver) { 588 pr_err("%s(): OSDQOver\n", __func__); 589 mutex_unlock(&av7110->dcomlock); 590 return -1; 591 } 592 #endif 593 594 for (i = 0; i < reply_buf_len; i++) 595 reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); 596 597 mutex_unlock(&av7110->dcomlock); 598 return 0; 599 } 600 601 static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16 *buf, s16 length) 602 { 603 int ret; 604 605 ret = av7110_fw_request(av7110, &tag, 0, buf, length); 606 if (ret) 607 pr_err("%s(): error %d\n", __func__, ret); 608 return ret; 609 } 610 611 /**************************************************************************** 612 * Firmware commands 613 ****************************************************************************/ 614 615 /* get version of the firmware ROM, RTSL, video ucode and ARM application */ 616 int av7110_firmversion(struct av7110 *av7110) 617 { 618 u16 buf[20]; 619 u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); 620 621 dprintk(4, "%p\n", av7110); 622 623 if (av7110_fw_query(av7110, tag, buf, 16)) { 624 pr_err("failed to boot firmware @ card %d\n", av7110->dvb_adapter.num); 625 return -EIO; 626 } 627 628 av7110->arm_fw = (buf[0] << 16) + buf[1]; 629 av7110->arm_rtsl = (buf[2] << 16) + buf[3]; 630 av7110->arm_vid = (buf[4] << 16) + buf[5]; 631 av7110->arm_app = (buf[6] << 16) + buf[7]; 632 av7110->avtype = (buf[8] << 16) + buf[9]; 633 634 pr_info("info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", 635 av7110->dvb_adapter.num, av7110->arm_fw, 636 av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); 637 638 /* print firmware capabilities */ 639 if (FW_CI_LL_SUPPORT(av7110->arm_app)) 640 pr_info("firmware @ card %d supports CI link layer interface\n", 641 av7110->dvb_adapter.num); 642 else 643 pr_info("no firmware support for CI link layer interface @ card %d\n", 644 av7110->dvb_adapter.num); 645 646 return 0; 647 } 648 649 int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst) 650 { 651 int i, ret; 652 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), 653 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 654 655 dprintk(4, "%p\n", av7110); 656 657 if (len > 10) 658 len = 10; 659 660 buf[1] = len + 2; 661 buf[2] = len; 662 663 if (burst != -1) 664 buf[3] = burst ? 0x01 : 0x00; 665 else 666 buf[3] = 0xffff; 667 668 for (i = 0; i < len; i++) 669 buf[i + 4] = msg[i]; 670 671 ret = av7110_send_fw_cmd(av7110, buf, 18); 672 if (ret && ret != -ERESTARTSYS) 673 pr_err("%s(): error %d\n", __func__, ret); 674 return ret; 675 } 676 677 #ifdef CONFIG_DVB_AV7110_OSD 678 679 static inline int SetColorBlend(struct av7110 *av7110, u8 windownr) 680 { 681 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); 682 } 683 684 static inline int SetBlend_(struct av7110 *av7110, u8 windownr, 685 enum av7110_osd_palette_type colordepth, u16 index, u8 blending) 686 { 687 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4, 688 windownr, colordepth, index, blending); 689 } 690 691 static inline int SetColor_(struct av7110 *av7110, u8 windownr, 692 enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo) 693 { 694 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5, 695 windownr, colordepth, index, colorhi, colorlo); 696 } 697 698 static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, 699 u16 colorfg, u16 colorbg) 700 { 701 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4, 702 windownr, fontsize, colorfg, colorbg); 703 } 704 705 static int FlushText(struct av7110 *av7110) 706 { 707 unsigned long start; 708 int err; 709 710 if (mutex_lock_interruptible(&av7110->dcomlock)) 711 return -ERESTARTSYS; 712 start = jiffies; 713 while (1) { 714 err = time_after(jiffies, start + ARM_WAIT_OSD); 715 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) 716 break; 717 if (err) { 718 pr_err("%s(): timeout waiting for BUFF1_BASE == 0\n", __func__); 719 mutex_unlock(&av7110->dcomlock); 720 return -ETIMEDOUT; 721 } 722 usleep_range(1000, 2000); 723 } 724 mutex_unlock(&av7110->dcomlock); 725 return 0; 726 } 727 728 static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) 729 { 730 int i, ret; 731 unsigned long start; 732 int length = strlen(buf) + 1; 733 u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; 734 735 if (mutex_lock_interruptible(&av7110->dcomlock)) 736 return -ERESTARTSYS; 737 738 start = jiffies; 739 while (1) { 740 ret = time_after(jiffies, start + ARM_WAIT_OSD); 741 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) 742 break; 743 if (ret) { 744 pr_err("%s(): timeout waiting for BUFF1_BASE == 0\n", __func__); 745 mutex_unlock(&av7110->dcomlock); 746 return -ETIMEDOUT; 747 } 748 usleep_range(1000, 2000); 749 } 750 #ifndef _NOHANDSHAKE 751 start = jiffies; 752 while (1) { 753 ret = time_after(jiffies, start + ARM_WAIT_SHAKE); 754 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) 755 break; 756 if (ret) { 757 pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__); 758 mutex_unlock(&av7110->dcomlock); 759 return -ETIMEDOUT; 760 } 761 usleep_range(1000, 2000); 762 } 763 #endif 764 for (i = 0; i < length / 2; i++) 765 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 766 swab16(*(u16 *)(buf + 2 * i)), 2); 767 if (length & 1) 768 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); 769 ret = __av7110_send_fw_cmd(av7110, cbuf, 5); 770 mutex_unlock(&av7110->dcomlock); 771 if (ret && ret != -ERESTARTSYS) 772 pr_err("%s(): error %d\n", __func__, ret); 773 return ret; 774 } 775 776 static inline int DrawLine(struct av7110 *av7110, u8 windownr, 777 u16 x, u16 y, u16 dx, u16 dy, u16 color) 778 { 779 return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6, 780 windownr, x, y, dx, dy, color); 781 } 782 783 static inline int DrawBlock(struct av7110 *av7110, u8 windownr, 784 u16 x, u16 y, u16 dx, u16 dy, u16 color) 785 { 786 return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6, 787 windownr, x, y, dx, dy, color); 788 } 789 790 static inline int HideWindow(struct av7110 *av7110, u8 windownr) 791 { 792 return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr); 793 } 794 795 static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y) 796 { 797 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y); 798 } 799 800 static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y) 801 { 802 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y); 803 } 804 805 static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) 806 { 807 return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr); 808 } 809 810 static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, 811 osd_raw_window_t disptype, 812 u16 width, u16 height) 813 { 814 return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4, 815 windownr, disptype, width, height); 816 } 817 818 static enum av7110_osd_palette_type bpp2pal[8] = { 819 Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit 820 }; 821 822 static osd_raw_window_t bpp2bit[8] = { 823 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8 824 }; 825 826 static inline int WaitUntilBmpLoaded(struct av7110 *av7110) 827 { 828 int ret = wait_event_timeout(av7110->bmpq, 829 av7110->bmp_state != BMP_LOADING, 10 * HZ); 830 if (ret == 0) { 831 pr_warn("warning: timeout waiting in LoadBitmap: %d, %d\n", ret, av7110->bmp_state); 832 av7110->bmp_state = BMP_NONE; 833 return -ETIMEDOUT; 834 } 835 return 0; 836 } 837 838 static inline int LoadBitmap(struct av7110 *av7110, 839 u16 dx, u16 dy, int inc, u8 __user *data) 840 { 841 u16 format; 842 int bpp; 843 int i; 844 int d, delta; 845 u8 c; 846 int ret; 847 848 dprintk(4, "%p\n", av7110); 849 850 format = bpp2bit[av7110->osdbpp[av7110->osdwin]]; 851 852 av7110->bmp_state = BMP_LOADING; 853 if (format == OSD_BITMAP8) { 854 bpp = 8; delta = 1; 855 } else if (format == OSD_BITMAP4) { 856 bpp = 4; delta = 2; 857 } else if (format == OSD_BITMAP2) { 858 bpp = 2; delta = 4; 859 } else if (format == OSD_BITMAP1) { 860 bpp = 1; delta = 8; 861 } else { 862 av7110->bmp_state = BMP_NONE; 863 return -EINVAL; 864 } 865 av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8; 866 av7110->bmpp = 0; 867 if (av7110->bmplen > 32768) { 868 av7110->bmp_state = BMP_NONE; 869 return -EINVAL; 870 } 871 for (i = 0; i < dy; i++) { 872 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) { 873 av7110->bmp_state = BMP_NONE; 874 return -EINVAL; 875 } 876 } 877 if (format != OSD_BITMAP8) { 878 for (i = 0; i < dx * dy / delta; i++) { 879 c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1]; 880 for (d = delta - 2; d >= 0; d--) { 881 c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d] 882 << ((delta - d - 1) * bpp)); 883 ((u8 *)av7110->bmpbuf)[1024 + i] = c; 884 } 885 } 886 } 887 av7110->bmplen += 1024; 888 dprintk(4, "av7110_fw_cmd(): LoadBmp size %d\n", av7110->bmplen); 889 ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); 890 if (!ret) 891 ret = WaitUntilBmpLoaded(av7110); 892 return ret; 893 } 894 895 static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y) 896 { 897 dprintk(4, "%p\n", av7110); 898 899 return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0); 900 } 901 902 static inline int ReleaseBitmap(struct av7110 *av7110) 903 { 904 dprintk(4, "%p\n", av7110); 905 906 if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e) 907 return -1; 908 if (av7110->bmp_state == BMP_LOADING) 909 dprintk(1, "%s called while BMP_LOADING\n", __func__); 910 av7110->bmp_state = BMP_NONE; 911 return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0); 912 } 913 914 static u32 RGB2YUV(u16 R, u16 G, u16 B) 915 { 916 u16 y, u, v; 917 u16 Y, Cr, Cb; 918 919 y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */ 920 u = 2048 + B * 8 - (y >> 5); /* Cr 0..4095 */ 921 v = 2048 + R * 8 - (y >> 5); /* Cb 0..4095 */ 922 923 Y = y / 256; 924 Cb = u / 16; 925 Cr = v / 16; 926 927 return Cr | (Cb << 16) | (Y << 8); 928 } 929 930 static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) 931 { 932 int ret; 933 934 u16 ch, cl; 935 u32 yuv; 936 937 yuv = blend ? RGB2YUV(r, g, b) : 0; 938 cl = (yuv & 0xffff); 939 ch = ((yuv >> 16) & 0xffff); 940 ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], 941 color, ch, cl); 942 if (!ret) 943 ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], 944 color, ((blend >> 4) & 0x0f)); 945 return ret; 946 } 947 948 static int OSDSetPalette(struct av7110 *av7110, u32 __user *colors, u8 first, u8 last) 949 { 950 int i; 951 int length = last - first + 1; 952 953 if (length * 4 > DATA_BUFF3_SIZE) 954 return -EINVAL; 955 956 for (i = 0; i < length; i++) { 957 u32 color, blend, yuv; 958 959 if (get_user(color, colors + i)) 960 return -EFAULT; 961 blend = (color & 0xF0000000) >> 4; 962 yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF, 963 (color >> 16) & 0xFF) | blend : 0; 964 yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); 965 wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4); 966 } 967 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4, 968 av7110->osdwin, 969 bpp2pal[av7110->osdbpp[av7110->osdwin]], 970 first, last); 971 } 972 973 static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, 974 int x1, int y1, int inc, u8 __user *data) 975 { 976 uint w, h, bpp, bpl, size, lpb, bnum, brest; 977 int i; 978 int rc, release_rc; 979 980 w = x1 - x0 + 1; 981 h = y1 - y0 + 1; 982 if (inc <= 0) 983 inc = w; 984 if (w <= 0 || w > 720 || h <= 0 || h > 576) 985 return -EINVAL; 986 bpp = av7110->osdbpp[av7110->osdwin] + 1; 987 bpl = ((w * bpp + 7) & ~7) / 8; 988 size = h * bpl; 989 lpb = (32 * 1024) / bpl; 990 bnum = size / (lpb * bpl); 991 brest = size - bnum * lpb * bpl; 992 993 if (av7110->bmp_state == BMP_LOADING) { 994 /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */ 995 if (WARN_ON(FW_VERSION(av7110->arm_app) >= 0x261e)) 996 return -EIO; 997 rc = WaitUntilBmpLoaded(av7110); 998 if (rc) 999 return rc; 1000 /* just continue. This should work for all fw versions 1001 * if bnum==1 && !brest && LoadBitmap was successful 1002 */ 1003 } 1004 1005 rc = 0; 1006 for (i = 0; i < bnum; i++) { 1007 rc = LoadBitmap(av7110, w, lpb, inc, data); 1008 if (rc) 1009 break; 1010 rc = BlitBitmap(av7110, x0, y0 + i * lpb); 1011 if (rc) 1012 break; 1013 data += lpb * inc; 1014 } 1015 if (!rc && brest) { 1016 rc = LoadBitmap(av7110, w, brest / bpl, inc, data); 1017 if (!rc) 1018 rc = BlitBitmap(av7110, x0, y0 + bnum * lpb); 1019 } 1020 release_rc = ReleaseBitmap(av7110); 1021 if (!rc) 1022 rc = release_rc; 1023 if (rc) 1024 dprintk(1, "returns %d\n", rc); 1025 return rc; 1026 } 1027 1028 int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) 1029 { 1030 int ret; 1031 1032 if (mutex_lock_interruptible(&av7110->osd_mutex)) 1033 return -ERESTARTSYS; 1034 1035 switch (dc->cmd) { 1036 case OSD_Close: 1037 ret = DestroyOSDWindow(av7110, av7110->osdwin); 1038 break; 1039 case OSD_Open: 1040 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7; 1041 ret = CreateOSDWindow(av7110, av7110->osdwin, 1042 bpp2bit[av7110->osdbpp[av7110->osdwin]], 1043 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); 1044 if (ret) 1045 break; 1046 if (!dc->data) { 1047 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1048 if (ret) 1049 break; 1050 ret = SetColorBlend(av7110, av7110->osdwin); 1051 } 1052 break; 1053 case OSD_Show: 1054 ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0); 1055 break; 1056 case OSD_Hide: 1057 ret = HideWindow(av7110, av7110->osdwin); 1058 break; 1059 case OSD_Clear: 1060 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); 1061 break; 1062 case OSD_Fill: 1063 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); 1064 break; 1065 case OSD_SetColor: 1066 ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); 1067 break; 1068 case OSD_SetPalette: 1069 if (FW_VERSION(av7110->arm_app) >= 0x2618) { 1070 ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0); 1071 } else { 1072 int i, len = dc->x0 - dc->color + 1; 1073 u8 __user *colors = (u8 __user *)dc->data; 1074 u8 r, g = 0, b = 0, blend = 0; 1075 1076 ret = 0; 1077 for (i = 0; i < len; i++) { 1078 if (get_user(r, colors + i * 4) || 1079 get_user(g, colors + i * 4 + 1) || 1080 get_user(b, colors + i * 4 + 2) || 1081 get_user(blend, colors + i * 4 + 3)) { 1082 ret = -EFAULT; 1083 break; 1084 } 1085 ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend); 1086 if (ret) 1087 break; 1088 } 1089 } 1090 break; 1091 case OSD_SetPixel: 1092 ret = DrawLine(av7110, av7110->osdwin, 1093 dc->x0, dc->y0, 0, 0, dc->color); 1094 break; 1095 case OSD_SetRow: 1096 dc->y1 = dc->y0; 1097 fallthrough; 1098 case OSD_SetBlock: 1099 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); 1100 break; 1101 case OSD_FillRow: 1102 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, 1103 dc->x1 - dc->x0 + 1, dc->y1, dc->color); 1104 break; 1105 case OSD_FillBlock: 1106 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, 1107 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color); 1108 break; 1109 case OSD_Line: 1110 ret = DrawLine(av7110, av7110->osdwin, 1111 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color); 1112 break; 1113 case OSD_Text: 1114 { 1115 char textbuf[240]; 1116 1117 if (strncpy_from_user(textbuf, dc->data, 240) < 0) { 1118 ret = -EFAULT; 1119 break; 1120 } 1121 textbuf[239] = 0; 1122 if (dc->x1 > 3) 1123 dc->x1 = 3; 1124 ret = SetFont(av7110, av7110->osdwin, dc->x1, 1125 (u16)(dc->color & 0xffff), (u16)(dc->color >> 16)); 1126 if (!ret) 1127 ret = FlushText(av7110); 1128 if (!ret) 1129 ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); 1130 break; 1131 } 1132 case OSD_SetWindow: 1133 if (dc->x0 < 1 || dc->x0 > 7) { 1134 ret = -EINVAL; 1135 } else { 1136 av7110->osdwin = dc->x0; 1137 ret = 0; 1138 } 1139 break; 1140 case OSD_MoveWindow: 1141 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1142 if (!ret) 1143 ret = SetColorBlend(av7110, av7110->osdwin); 1144 break; 1145 case OSD_OpenRaw: 1146 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) { 1147 ret = -EINVAL; 1148 break; 1149 } 1150 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) 1151 av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1; 1152 else 1153 av7110->osdbpp[av7110->osdwin] = 0; 1154 ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color, 1155 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); 1156 if (ret) 1157 break; 1158 if (!dc->data) { 1159 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1160 if (!ret) 1161 ret = SetColorBlend(av7110, av7110->osdwin); 1162 } 1163 break; 1164 default: 1165 ret = -EINVAL; 1166 break; 1167 } 1168 1169 mutex_unlock(&av7110->osd_mutex); 1170 if (ret == -ERESTARTSYS) 1171 dprintk(1, "%s(%d) returns with -ERESTARTSYS\n", __func__, dc->cmd); 1172 else if (ret) 1173 dprintk(1, "%s(%d) returns with %d\n", __func__, dc->cmd, ret); 1174 1175 return ret; 1176 } 1177 1178 int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) 1179 { 1180 switch (cap->cmd) { 1181 case OSD_CAP_MEMSIZE: 1182 if (FW_4M_SDRAM(av7110->arm_app)) 1183 cap->val = 1000000; 1184 else 1185 cap->val = 92000; 1186 return 0; 1187 default: 1188 return -EINVAL; 1189 } 1190 } 1191 #endif /* CONFIG_DVB_AV7110_OSD */ 1192