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