Skip to content

Commit

Permalink
fix low resolutions and stability fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
rhgndf committed May 1, 2022
1 parent 4b6dd9d commit f25190c
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 75 deletions.
78 changes: 78 additions & 0 deletions captures/parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import json
import sys

filename = sys.argv[1]
usbaddr = sys.argv[2]

registers = open('../fl2000_registers.h')

registermaps = {}
registernames = {}
registervalue = {}
registerseen = {}
defines = {}

curmap = 0
curoffset = 0
for line in registers.readlines():
if line.startswith("#define"):
tokens = line.split(" ")
if "+" in line:
name = tokens[1]
offset = defines[tokens[2].split("(")[1]] + int(tokens[4].split(")")[0],16)
registermaps[offset] = []
registernames[offset] = name
registervalue[offset] = 0
registerseen[offset] = 0
curmap = offset
else:
if len(tokens) > 2 and tokens[2].startswith("0x"):
defines[tokens[1]] = int(tokens[2], 16)
elif ':' in line and not line.startswith("/*") and ';' in line:
tokens = line.split(":")
name = tokens[0].split(" ")[-2]
bitlength = tokens[1].split(" ")[1].split(";")[0]
registermaps[curmap].append((name, int(bitlength)))

capture = json.load(open(filename))

def getfields(address, value):
maps = []
if registerseen[address]:
changed = value ^ registervalue[address]
else:
changed = 0
registerseen[address] = 1
registervalue[address] = value
for field in registermaps[address]:
fieldvalue = value & (2**field[1]-1)
fieldchanged = changed & (2**field[1]-1)
maps.append((field[0], fieldvalue, fieldchanged))
value >>= field[1]
changed >>= field[1]
return maps

def handle_packet(time, direction, address, value):
if direction:
print(time + " WR 0x{:04x} ".format(address) + value)
else:
print(time + " RD 0x{:04x} ".format(address) + value)
fields = getfields(address,int(value,16))
print(" " + registernames[address])
for field in fields:
print(" " + field[0].ljust(25) + " = " + str(field[1]).ljust(6) + " " + hex(field[1]).ljust(6) + (" ***CHANGED***" if field[2] else ""))
rd_data = ""
for packet in capture:
if packet["_source"]["layers"]["usb"]["usb.src"] != usbaddr and packet["_source"]["layers"]["usb"]["usb.dst"] != usbaddr:
continue
if packet["_source"]["layers"]["usb"]["usb.transfer_type"] != "0x02":
continue
if "usb.control.Response" in packet["_source"]["layers"]:
handle_packet(packet["_source"]["layers"]["frame"]["frame.time"], 0, rd_data, "".join(packet["_source"]["layers"]["usb.control.Response"].split(":")[::-1]))
if "Setup Data" not in packet["_source"]["layers"]:
continue
request = packet["_source"]["layers"]["Setup Data"]
if packet["_source"]["layers"]["Setup Data"]["usb.bmRequestType"] == "0xc0":
rd_data = int(request["usb.setup.wIndex"])
if packet["_source"]["layers"]["Setup Data"]["usb.bmRequestType"] == "0x40" and "usb.data_fragment" in request:
handle_packet(packet["_source"]["layers"]["frame"]["frame.time"], 1, int(request["usb.setup.wIndex"]), "".join(request["usb.data_fragment"].split(":")[::-1]))
33 changes: 5 additions & 28 deletions fl2000.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,12 @@
#ifndef __FL2000_DRM_H__
#define __FL2000_DRM_H__

#include <linux/version.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/component.h>
#include <linux/regmap.h>
#include <linux/vmalloc.h>
#include <linux/dma-buf.h>
#include <linux/dma-mapping.h>
#include <linux/time.h>
#include <linux/device.h>
#include <drm/drm_gem.h>
#include <drm/drm_prime.h>
#include <drm/drm_vblank.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_drv.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_atomic_helper.h>

#include <drm/drm_modes.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_managed.h>

#include "fl2000_registers.h"

Expand Down Expand Up @@ -160,6 +135,8 @@ struct fl2000 {

struct usb_anchor anchor;

int print_complete;

/* Interrupt handling */
u8 poll_interval;
struct urb *intr_urb;
Expand Down
6 changes: 6 additions & 0 deletions fl2000_connector.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@

#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_probe_helper.h>

#include "fl2000.h"

static int fl2000_read_edid(void *data, u8 *buf, unsigned int block, size_t len)
Expand Down
67 changes: 48 additions & 19 deletions fl2000_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@
* (C) Copyright 2018-2020, Artem Mygaiev
*/

#include "fl2000.h"
#include <linux/dma-buf.h>
#include <linux/printk.h>
#include <linux/usb.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>

#include "fl2000.h"

#define DRM_DRIVER_NAME "fl2000_drm"
#define DRM_DRIVER_DESC "USB-VGA/HDMI"
Expand All @@ -16,8 +30,8 @@
#define DRM_DRIVER_PATCHLEVEL 1

/* Maximum supported resolution, out-of-the-blue numbers */
#define FL20000_MAX_WIDTH 4000
#define FL20000_MAX_HEIGHT 4000
#define FL2000_MAX_WIDTH 4000
#define FL2000_MAX_HEIGHT 4000

/* Force using 32-bit XRGB8888 on input for simplicity */
#define FL2000_FB_BPP 32
Expand Down Expand Up @@ -350,7 +364,7 @@ static void fl2000_display_enable(struct drm_simple_display_pipe *pipe,

fl2000_stream_enable(fl2000_dev);

//drm_crtc_vblank_on(crtc);
drm_crtc_vblank_on(crtc);
}

static void fl2000_display_disable(struct drm_simple_display_pipe *pipe)
Expand All @@ -359,7 +373,7 @@ static void fl2000_display_disable(struct drm_simple_display_pipe *pipe)
struct drm_device *drm = pipe->crtc.dev;
struct fl2000 *fl2000_dev = drm->dev_private;

//drm_crtc_vblank_off(crtc);
drm_crtc_vblank_off(crtc);

fl2000_stream_disable(fl2000_dev);
}
Expand Down Expand Up @@ -390,11 +404,6 @@ static void fb2000_dirty(struct drm_framebuffer *fb,
struct drm_device *drm = fb->dev;
struct fl2000 *fl2000_dev = drm->dev_private;

if (!drm_dev_enter(fb->dev, &idx)) {
dev_err(drm->dev, "DRM enter failed!");
return;
}

ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
if (ret)
return;
Expand All @@ -403,8 +412,6 @@ static void fb2000_dirty(struct drm_framebuffer *fb,
fb->pitches[0]);

drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);

drm_dev_exit(idx);
}

static void fl2000_display_update(struct drm_simple_display_pipe *pipe,
Expand All @@ -416,9 +423,29 @@ static void fl2000_display_update(struct drm_simple_display_pipe *pipe,
struct drm_shadow_plane_state *shadow_plane_state =
to_drm_shadow_plane_state(state);
struct drm_rect rect;
struct drm_pending_vblank_event *event = crtc->state->event;
int idx;

if (!drm_dev_enter(drm, &idx)) {
dev_err(drm->dev, "DRM enter failed!");
return;
}

if (drm_atomic_helper_damage_merged(old_state, state, &rect))
fb2000_dirty(state->fb, &shadow_plane_state->map[0], &rect);
fb2000_dirty(state->fb, &shadow_plane_state->data[0], &rect);

drm_dev_exit(idx);

if (event) {
crtc->state->event = NULL;

spin_lock_irq(&drm->event_lock);
if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
drm_crtc_arm_vblank_event(crtc, event);
else
drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irq(&drm->event_lock);
}
}

/* Logical pipe management (no HW configuration here) */
Expand Down Expand Up @@ -472,9 +499,9 @@ int fl2000_drm_init(struct fl2000 *fl2000_dev)
mode_config = &drm->mode_config;
mode_config->funcs = &fl2000_mode_config_funcs;
mode_config->min_width = 1;
mode_config->max_width = FL20000_MAX_WIDTH;
mode_config->max_width = FL2000_MAX_WIDTH;
mode_config->min_height = 1;
mode_config->max_height = FL20000_MAX_HEIGHT;
mode_config->max_height = FL2000_MAX_HEIGHT;
mode_config->prefer_shadow = 0;
mode_config->preferred_depth = FL2000_FB_BPP;

Expand Down Expand Up @@ -517,12 +544,12 @@ int fl2000_drm_init(struct fl2000 *fl2000_dev)

drm_mode_config_reset(drm);

/*ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret) {
dev_err(drm->dev, "Failed to initialize %d VBLANK(s) (%d)",
drm->mode_config.num_crtc, ret);
goto err_intr_release;
}*/
}

drm_kms_helper_poll_init(drm);

Expand Down Expand Up @@ -554,10 +581,12 @@ void fl2000_drm_release(struct fl2000 *fl2000_dev)
{
struct drm_device *drm = &fl2000_dev->drm;

/* Start streaming interface */
drm_crtc_vblank_off(&fl2000_dev->pipe.crtc);

/* Stop streaming interface */
fl2000_stream_release(fl2000_dev);

/* Start interrupts interface */
/* Stop interrupts interface */
fl2000_intr_release(fl2000_dev);

/* Prepare to DRM device shutdown */
Expand Down
8 changes: 8 additions & 0 deletions fl2000_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
* (C) Copyright 2018-2020, Artem Mygaiev
*/

#include <drm/drm_drv.h>

#include <linux/module.h>
#include <linux/usb.h>

#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper.h>

#include "fl2000.h"

#define USB_DRIVER_NAME "fl2000_usb"
Expand Down
1 change: 0 additions & 1 deletion fl2000_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* (C) Copyright 2017, Fresco Logic, Incorporated.
* (C) Copyright 2018-2019, Artem Mygaiev
*/

#include "fl2000.h"

/* I2C controller require mandatory 8-bit (1 bite) sub-address provided for any read/write
Expand Down
2 changes: 2 additions & 0 deletions fl2000_interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* (C) Copyright 2018-2020, Artem Mygaiev
*/

#include <drm/drm_probe_helper.h>

#include "fl2000.h"

#define INTR_BUFSIZE 1
Expand Down
4 changes: 2 additions & 2 deletions fl2000_registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* (C) Copyright 2017, Fresco Logic, Incorporated.
* (C) Copyright 2018-2019, Artem Mygaiev
*/
#include <linux/regmap.h>

#include "fl2000.h"

Expand Down Expand Up @@ -117,7 +118,6 @@ int fl2000_set_pll(struct usb_device *usb_dev, struct fl2000_pll *pll)
pll_reg.function = pll->function;
regmap_write(regmap, FL2000_VGA_PLL_REG, pll_reg.val);

dev_info(&usb_dev->dev, "pll reg %x", pll_reg.val);
aclk.force_pll_up = true;
fl2000_add_bitmask(mask, union fl2000_vga_ctrl_reg_aclk, force_pll_up);
//aclk.force_vga_connect = true;
Expand Down Expand Up @@ -165,7 +165,7 @@ int fl2000_set_pixfmt(struct usb_device *usb_dev, u32 bytes_pix)
pxclk.dac_output_en = false;
fl2000_add_bitmask(mask, union fl2000_vga_cntrl_reg_pxclk,
dac_output_en);
regmap_write_bits(regmap, FL2000_VGA_CTRL_REG_PXCLK, mask, pxclk.val);
//regmap_write_bits(regmap, FL2000_VGA_CTRL_REG_PXCLK, mask, pxclk.val);
pxclk.drop_cnt = false;
fl2000_add_bitmask(mask, union fl2000_vga_cntrl_reg_pxclk, drop_cnt);
pxclk.vga565_mode = (bytes_pix == 2);
Expand Down
Loading

0 comments on commit f25190c

Please sign in to comment.