koreader-base icon indicating copy to clipboard operation
koreader-base copied to clipboard

Pocketbook: Make distinction between NTX and Allwinner boards

Open ezdiy opened this issue 3 years ago • 9 comments

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 https://github.com/koreader/koreader/issues/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);

ezdiy avatar Sep 26 '20 21:09 ezdiy

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).

NiLuJe avatar Sep 27 '20 03:09 NiLuJe

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 ^^).

NiLuJe avatar Sep 27 '20 03:09 NiLuJe

Also possibly relevant: https://github.com/pocketbook/Platform_A13/blob/master/Kernel/include/linux/drv_display_sun4i.h & https://github.com/pocketbook/Platform_A13/blob/master/Kernel/drivers/video/sun5i/disp/dev_disp.c

NiLuJe avatar Sep 27 '20 03:09 NiLuJe

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.

ezdiy avatar Sep 27 '20 04:09 ezdiy

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 :>

ezdiy avatar Sep 27 '20 04:09 ezdiy

Now this looks somewhat related -

https://github.com/pocketbook/Platform_A13/blob/master/Kernel/drivers/video/sun5i/disp/dev_fb.c

https://github.com/pocketbook/Platform_A13/blob/master/Kernel/drivers/video/sun5i/disp/de_bsp/de/mxcfb.h

However the real ko seems like reimplementation with a lot of cruft stripped down.

ezdiy avatar Sep 27 '20 04:09 ezdiy

@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.

NiLuJe avatar Sep 28 '20 12:09 NiLuJe

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.

ezdiy avatar Sep 28 '20 15:09 ezdiy

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

roshavagarga avatar Dec 05 '21 12:12 roshavagarga

@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?

rjd22 avatar Dec 20 '22 21:12 rjd22

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

NiLuJe avatar Dec 20 '22 22:12 NiLuJe

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).

NiLuJe avatar Dec 20 '22 22:12 NiLuJe