koreader / koreader-base

Base framework offering a Lua scriptable environment for creating document readers

Home Page:http://koreader.rocks/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pocketbook: Make distinction between NTX and Allwinner boards

ezdiy opened this issue · comments

commented

Reverse engineered the epdc.ko driver yesterday, so this is mostly infodump. Today @EastEriq accidentally discovered that PB631 is an NTX board, which finally paints the full picture of what goes on:

PB631:

/mnt/secure # cat /proc/cpuinfo
Processor	: ARMv7 Processor rev 10 (v7l)
BogoMIPS	: 790.52
Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 10

Hardware	: Freescale i.MX 6SoloLite NTX Board
Revision	: 60200
Serial		: 081069d4e6fed102
/mnt/secure

PB740-2:

/mnt/secure # cat /proc/cpuinfo 
processor	: 0
model name	: ARMv7 Processor rev 5 (v7l)
BogoMIPS	: 11.42
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 5

processor	: 1
model name	: ARMv7 Processor rev 5 (v7l)
BogoMIPS	: 11.42
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 5

Hardware	: sun8iw10
Revision	: 0000
Serial		: 0000000000000000
/mnt/secure # 

This is why koreader kept crashing on his reader in koreader/koreader#6000 while it didn't for others. Because on almost all other models, there's no mxc, but epdc.ko. That one is a closed source, messy driver exclusively for B288 integrated controller. It emulates MXC interface just barely, but works rather differently past that. We'd need to account for it in order to get decent performance - have one branch of code for Freescale, probably sharing much in common with kobo/Cervantes/other NXT boards, and second branch for Allwinner that will account for hacks special to their driver.

Their driver has only 4 ioctls:

MXCFB_SEND_UPDATE

if (param_2 == 0x4040462e) { // _IOW('F', 0x2E, struct mxcfb_update_data)
...
iVar3 = __copy_from_user(&local_60,param_3,0x40);
...
// It writes back, contrary to what ioctl macro! The horror ...
iVar3 = __copy_to_user(param_3,&local_60,0x40);

The struct is largely same as MXC one for rect and waveform field, which is why it works for us in the first place, however nearly all the other flags are different. Quite notably, there are even flags to upload waveforms and such, its pretty much all-in-one call for almost everything the driver does, all commanded by a weird forest of custom flags further down in the update struct.

MXCFB_WAIT_FOR_UPDATE_COMPLETE

      if (param_2 != 0x4004462f) { // _IOW('F', 0x2F, __u32)
        return 0;
      }
      epdc_wait_complete() =>
....
  while (iVar1 = ppm_is_active(), iVar1 != 0) {
    usleep_range(10000);
  }
....

This one simply waits until epdc stops being busy. Markers are ignored, and nothing is written back. On a real NXT, I presume Pocketbook guys just hacked the Freescale driver to accept this ioctl opcode inside _IOWR('F', 0x35, struct mxcfb_update_marker_data) handler, but forgot to nuke the writeback code.

The third one is same thing, but this time it polls without blocking:

B288_POLL_FOR_UPDATE_COMPLETE

if (param_2 == 0x80044655) {
local_60 = epdc_get_update_state() =>
   ppm_is_active();
...
uVar4 = 4;
...
iVar3 = __copy_to_user(param_3,&local_60,uVar4);
...

It also writes back 32bit int with the busy state.

The last one is not really clear what it does. It seems to report back 32 bytes of some temperature/WF timing information.

B288_UNKNOWN

      if (param_2 != 0x80204656) {
        return 0;
      }
      pbVar6 = (byte *)0xe3;
      iVar3 = epdc_waveform_tempindex(_DAT_00000004);
      puVar8 = &uStack98;
      piVar7 = (int *)((iVar3 + 0x43d) * 4);
      do {
        pbVar6 = pbVar6 + 1;
        uVar2 = (ushort)*pbVar6;
        if (*pbVar6 != 0) {
          uVar2 = __aeabi_idiv(*piVar7 * 1000);
        }
        puVar8 = puVar8 + 1;
        *puVar8 = uVar2;
        piVar7 = piVar7 + 0x20;
      } while (pbVar6 != (byte *)0xf3);
      iVar3 = *(int *)(((uint)auStack112 & 0xffffe000) + 8);
      bVar9 = 0xffffffdf < param_3;
      if (!bVar9) {
        bVar9 = iVar3 + (uint)!bVar9 <= param_3 + 0x20;
      }
      if (!bVar9) {
        iVar3 = 0;
      }
      if (iVar3 == 0) {
        uVar4 = 0x20;
LAB_000122b8:
        iVar3 = __copy_to_user(param_3,&local_60,uVar4);

You might want to look at the WIP Booken support issue/tree, the platform is based on an AW board, and possibly the same crappy driver (except we do have the sources there ;p).

At a very quick glance, that does indeed look like the same sunxi/epdc mess. Or similar at the very least (e.g., I definitely remember the markerless crap wait_for_complete).

I've also got an untested strace patch for those, and apparently I'd also built one ;D.

(Also untested, but the actual PR was similar, and was tested on that front, at least for the basics ^^).

commented

The driver doesn't match on interface end, but deeper on the internal level there's indeed structures resembling the ones passed to Disp_eink_update. What I'm interested in is mostly hwinvert, and dealing with update rect scheduling - currently updates often flash randomly sized rects, sometimes much larger than original update slowing screen updates noticeably. This is most likely due to rect combining code in the driver, so ideally I'd like to trick it somehow to prevent that crap.

commented

As for 631 kernel, it seems the source indeed matches the behavior - https://github.com/pocketbook/Platform_MX6/blob/master/Kernel_631/drivers/video/mxc/mxc_epdc_fb.c#L3941

Notice the comment where things were brutalized :>

@roshavagarga just pointed out that https://github.com/pocketbook/kernel-b288 popped up earlier this month, I hadn't noticed ;).

https://github.com/pocketbook/kernel-b288/blob/master/include/video/sunxi_display2.h
https://github.com/pocketbook/kernel-b288/tree/master/drivers/video/sunxi

EDIT: Well, it has the DISP_EINK ioctls commented out, so, I have no idea where they're using that ;D.

commented

Oh, nice find - and also kudoz to Pocketbook, still better later than never like most other vendors do :>

These two match large portions of disassembled code:

https://github.com/pocketbook/kernel-b288/blob/master/drivers/video/sunxi/disp2/disp/dev_fb.c#L254
https://github.com/pocketbook/kernel-b288/blob/master/drivers/video/sunxi/disp2/disp/de/disp_eink_manager.c#L392

and https://github.com/pocketbook/kernel-b288/blob/master/drivers/video/sunxi/disp2/disp/eink.h for headers.

Still - no HW invert, and the rotations as well as update combining is buggy/weird as expected - at least we can infer how buggy exactly:

https://github.com/pocketbook/kernel-b288/blob/master/drivers/video/sunxi/disp2/disp/de/disp_eink_manager.c#L501

I don't understand how really the rect splitting works, but from the glance it seems to re-combine with collisions that are pending. This could be huge deal if we could feed it things to recombine whenever it is actually safe to do so (ie the area is fine with GC demoted to DU from our perspective). Remember that we don't get proper notifications/wait for update to complete - the driver is essentially stuck in auto update mode. So if we use DU/AUTO/GC16 without that in mind, DU gets applied in places where it shouldn't, or GC16 gets applied in areas that were DU due to a recombine producing an update glitch.

Finally there's this GS16 thing that might be of benefit compared to GL16.

Leaving this here for anyone that might pick this work up at some point, might be useful: https://github.com/pocketbook/uboot_b288

@NiLuJe As far as I understand correctly this ticket has to do with the mxcfb implementation that we're not using anymore since we switched to inkview, right?

Would we still need this ticket open?

Not as such, but it is interesting nonetheless (and the NTX/AW distinction might come back to bite us in the ass later anyway ^^).

Because I don't remember if I mentioned this (and if so, where): what popped up on the AW B300 boards from NTX used on the Kobo Sage/Elipsa, with a "disp2" display driver, only bears a vague resemblance to this one ;). (It's still a horrible mess, though).