Difference between revisions of "RK3566 EBC Reverse-Engineering"

Jump to navigation Jump to search
(→‎Structs: Add rk_waveform struct)
 
(5 intermediate revisions by 2 users not shown)
Line 11: Line 11:
The files of interest are <code>ebc_dev_v8.S</code>, which implements a DRM (Direct Rendering Manager) driver for the eInk panel, and the waveform files in the <code>epdlut</code> subdirectory.
The files of interest are <code>ebc_dev_v8.S</code>, which implements a DRM (Direct Rendering Manager) driver for the eInk panel, and the waveform files in the <code>epdlut</code> subdirectory.


There's also a completely open-source simple driver for u-boot: [https://github.com/JeffyCN/rockchip_mirrors/tree/u-boot/drivers/video/rk_eink drivers/video/rk_eink at JeffyCN/rockchip_mirrors]
There's also a simple driver for u-boot: [https://github.com/JeffyCN/rockchip_mirrors/tree/u-boot/drivers/video/rk_eink drivers/video/rk_eink at JeffyCN/rockchip_mirrors]
 
These two drivers show the two different programming interfaces exposed by the TCON. The U-Boot driver operates in "LUT mode": it writes the waveform LUT to registers in the TCON's MMIO space, and passes buffers of ''pixel'' data to the TCON. The Linux driver operates in "direct mode" uses the LUTs to compute waveforms in software, and passes buffers of ''waveform'' data to the TCON.
 
Some reversing of the downstream Linux driver has been done here: https://github.com/Ralim/ebc-dev-reverse-engineering
 
== Reimplementation ==
 
A human-readable C reimplementation of the LUT and pixel data path [https://gitlab.com/smaeul/ebc-dev is available from smaeul here]. This provides everything needed to convert a framebuffer and a waveform data file into a series of "frames" for the panel. The new implementation includes a test suite to verify its output matches the output from the BSP assembly code. It is based on the downstream Linux driver.


== In-Development Driver ==
== In-Development Driver ==


[https://gitlab.com/pine64-org/quartz-bsp/linux-next/-/tree/rk356x-ebc-dev rk356x-ebc-dev] is the branch on the pine64 linux-next repository used for developing an upstreamable driver based on mainline kernel sources.
[https://github.com/smaeul/linux/commits/rk356x-ebc-dev rk356x-ebc-dev] is the branch used for developing an upstreamable DRM driver based on mainline kernel sources. The driver currently functions well enough to get a virtual console and Xorg running, but it does not support features like multiple waveforms.


= Documentation =
= Documentation =


== Datasheets ==
== Datasheets ==
=== EBC ===
The EBC TCON is documented in part 2 of the RK356x TRM.


=== TI TPS65185x ===
=== TI TPS65185x ===
Line 26: Line 38:


https://www.ti.com/lit/ds/symlink/tps65185.pdf
https://www.ti.com/lit/ds/symlink/tps65185.pdf
=== Waveform ===
The format of the waveform file is documented here:
https://www.waveshare.net/w/upload/c/c4/E-paper-mode-declaration.pdf
https://www.waveshare.net/w/upload/archive/c/c4/20190611032540!E-paper-mode-declaration.pdf
== Utilities ==
The [https://github.com/fread-ink/inkwave <tt>inkwave</tt>] program is designed to parse waveform files. Currently it cannot fully handle the waveform files shipped with the PineNote. Adding support for this to the tool would be helpful.


== Assembly Syntax and Semantics ==
== Assembly Syntax and Semantics ==
Line 154: Line 178:
<!-- I don't know why mediawiki scuffs the formatting here -->
<!-- I don't know why mediawiki scuffs the formatting here -->


<source lang="c">
See https://gitlab.com/smaeul/ebc-dev/-/blob/main/auto_image.h#L124, which is based on [https://gitlab.com/pine64-org/quartz-bsp/linux-next/-/commits/2de5fb11a888c37f366642544e5a53ec2faae32d the v1.04 BSP Linux driver].
struct ebc_info {
    long unsigned int ebc_buffer_phy;
    char* ebc_buffer_vir;
    int ebc_buffer_size;
    int ebc_buf_real_size;
    int direct_buf_real_size;
    int is_busy_now;
    int task_restart;
    int auto_refresh_done;
    char frame_total;
    char frame_bw_total;
    int auto_need_refresh0;
    int auto_need_refresh1;
    int frame_left;
    int part_mode_count;
    int full_mode_num;
    int height;
    int width;
    int* lut_addr;
    int buffer_need_check;
    int ebc_irq_status;
    int ebc_dsp_buf_status;
    struct device* dev;
    struct epd_lut_data lut_data;
    struct task_struct* ebc_task;
    int* auto_image_new;
    int* auto_image_old;
    int* auto_image_bg;
    int* auto_image_cur;
    u8* auto_frame_count;
    int* auto_image_fb;
    void* direct_buffer;
    int ebc_power_status;
    int ebc_last_display;
    char* lut_ddr_vir;
    struct ebc_buf_s* prev_dsp_buf;
    struct ebc_buf_s* curr_dsp_buf;
    struct wake_lock suspend_lock;
    int wake_lock_is_set;
    int first_in;
    struct timer_list vdd_timer;
    struct timer_list frame_timer;
    struct work_struct auto_buffer_work;
    int is_early_suspend;
    int is_deep_sleep;
    int is_power_off;
    int overlay_enable;
    int overlay_start;
};
</source>


=== ebc ===
=== ebc ===


<source lang="c">
See https://gitlab.com/smaeul/ebc-dev/-/blob/main/auto_image.h#L200, which is based on [https://gitlab.com/pine64-org/quartz-bsp/linux-next/-/commits/2de5fb11a888c37f366642544e5a53ec2faae32d the v1.04 BSP Linux driver].
struct ebc {
 
    struct device* dev;
=== rkf_waveform ===
    struct ebc_tcon* tcon;
    struct ebc_pmic* pmic;
    struct ebc_panel* panel;
    struct ebc_info* info;
};
</source>


=== rk_waveform ===
Note: all known waveform data files are the "PVI" variant, not the "RKF" variant.


<source lang="c">
<source lang="c">
struct rk_waveform {
struct rkf_waveform {
     int length,
     int length,
     char[16] format,
     char[16] format,
111

edits

Navigation menu