Skip to content
This repository has been archived by the owner on Jul 7, 2021. It is now read-only.

Development

notro edited this page Mar 3, 2017 · 17 revisions

struct tinydrm_panel

I'm working on an abstraction that I hope to get merged in some form: tinydrm-panel.h, tinydrm-panel.c

Documentation

Build documentation:

# install sphinx
$ make htmldocs

Result is in Documentation/output.

PRIME

I did a test some months back using a hacked modetest rendering a dumb buffer on vc4 and scanned out with tinydrm. This worked.

I recently tried the same using X windows, but failed: https://github.com/anholt/linux/issues/10

modetest

modetest is a simple tool to test drm drivers.

Build

$ sudo apt-get -y install autoconf libtool xutils-dev libpthread-stubs0-dev

$ git clone https://github.com/freedreno/libdrm
$ cd libdrm
$ ./autogen.sh
$ make

Find connector id

$ ./tests/modetest/modetest -M "mi0283qt" -c

Connectors:
id      encoder status          name            size (mm)       modes   encoders
25      28      connected       Virtual-1       58x43           1       28
  modes:
        name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
  320x240 0 320 320 320 320 240 240 240 240 1 flags: ; type: preferred, driver
  props:
        2 DPMS:
                flags: enum
                enums: On=0 Standby=1 Suspend=2 Off=3
                value: 0

Display a test image

$ ./tests/modetest/modetest -M "mi0283qt" -s 25:320x240@RG16
setting mode 320x240-0Hz@RG16 on connectors 25, crtc 27

<press enter to stop>

(RG16 is RGB565, XR24 is XRGB8888)

How fast is it

$ ./tests/modetest/modetest -M "mi0283qt" -s 25:320x240@RG16 -v
setting mode 320x240-0Hz@RG16 on connectors 25, crtc 27
freq: 31.44Hz
freq: 31.44Hz
freq: 31.44Hz
freq: 31.44Hz
freq: 31.44Hz

<press enter to stop>

Debug

drm_debug

Turn on most drm debug messages

$ echo 0xf | sudo tee /sys/module/drm/parameters/debug

From include/drm/drmP.h

#define DRM_UT_CORE             0x01
#define DRM_UT_DRIVER           0x02
#define DRM_UT_KMS              0x04
#define DRM_UT_PRIME            0x08
#define DRM_UT_ATOMIC           0x10
#define DRM_UT_VBL              0x20
#define DRM_UT_STATE            0x40

mipi_dbi

Turn on and off display:

$ echo "28" | sudo tee /sys/kernel/debug/dri/0/command
$ echo "29" | sudo tee /sys/kernel/debug/dri/0/command

Dump MIPI DCS commands:

$ sudo cat /sys/kernel/debug/dri/0/command
04: 000000
06: 00
07: 00
08: 00
09: 94530400
0a: 9c
0b: 28
0c: 05
0d: 00
0e: 00
0f: c0
2e: 00c4
3e: 00c4
45: 00
52: 00
54: 00
56: 00
5f: 00
a1: 00
a8: 00

Use tool from tinydrm repo:

$ sudo ./tinydrm/tools/mipi-dcs
File: /sys/kernel/debug/dri/0/command

GET_DISPLAY_ID(04h): 000000 (0b0)
    ID1 = 00
    ID2 = 00
    ID3 = 00
GET_RED_CHANNEL(06h): 00 (0b0)
GET_GREEN_CHANNEL(07h): 00 (0b0)
GET_BLUE_CHANNEL(08h): 00 (0b0)
GET_DISPLAY_STATUS(09h): 94530400 (0b10010100010100110000010000000000)
    D31=1: Booster voltage status: On
    D30=0: Row address order
    D29=0: Column address order
    D28=1: Row/column exchange
    D27=0: Vertical refresh: Top to Bottom
    D26=1: RGB/BGR order: BGR
    D25=0: Horizontal refresh order: Left to Right
    D24=0: Reserved
    D23=0: Reserved
    D[22:20]=2373: Interface color pixel format: 1 0 1
    D19=0: Idle mode: Off
    D18=0: Partial mode: Off
    D17=1: Sleep: Out
    D16=1: Display normal mode: On
    D15=0: Vertical scrolling status: Off
    D14=0: Reserved
    D13=0: Inversion status
    D12=0: All pixel ON
    D11=0: All pixel OFF
    D10=1: Display: On
    D9=0: Tearing effect line: Off
    D[8:6]=38882320: Gamma curve selection: 0 0 0
    D5=0: Tearing effect line mode: Mode 1, V-Blanking only
    D4=0: Reserved
    D3=0: Reserved
    D2=0: Reserved
    D1=0: Reserved
    D0=0: Reserved
GET_POWER_MODE(0Ah): 9c (0b10011100)
    D7=1: Booster On
    D6=0: Idle Mode Off
    D5=0: Partial Mode Off
    D4=1: Sleep Out Mode
    D3=1: Display Normal Mode On
    D2=1: Display is On
    D1=0: Reserved
    D0=0: Reserved
GET_ADDRESS_MODE(0Bh): 28 (0b101000)
    D7=0: Page Address Order: Top to Bottom
    D6=0: Column Address Order: Left to Right
    D5=1: Page/Column Order: Reverse Mode
    D4=0: Line Address Order: LCD Refresh Top to Bottom
    D3=1: RGB/BGR Order: BGR
    D2=0: Display Data Latch Data Order: LCD Refresh Left to Right
    D1=0: Reserved
    D0=0: Reserved
GET_PIXEL_FORMAT(0Ch): 05 (0b101)
    D7=0: Reserved
    D[6:4]=0: DPI: Reserved
    D3=0: Reserved
    D[2:0]=5: DBI: 16 bits/pixel
GET_DISPLAY_MODE(0Dh): 00 (0b0)
    D7=0: Vertical Scrolling Status: Off
    D6=0: Reserved
    D5=0: Inversion: Off
    D4=0: Reserved
    D3=0: Reserved
    D[2:0]=0: Gamma Curve Selection: GC0
GET_SIGNAL_MODE(0Eh): 00 (0b0)
    D7=0: Tearing Effect Line: Off
    D6=0: Tearing Effect Line Output Mode: Mode 1
    D5=0: Reserved
    D4=0: Reserved
    D3=0: Reserved
    D2=0: Reserved
    D1=0: Reserved
    D0=0: Reserved
GET_DIAGNOSTIC_RESULT(0Fh): c0 (0b11000000)
    D7=1: Register Loading Detection: OK
    D6=1: Functionality Detection: OK
    D5=0: Chip Attachment Detection: OK or unimplemented
    D4=0: Display Glass Break Detection: OK or unimplemented
    D3=0: Reserved
    D2=0: Reserved
    D1=0: Reserved
    D0=0: Reserved
READ_MEMORY_START(2Eh): 0000 (0b0)
READ_MEMORY_CONTINUE(3Eh): 0000 (0b0)
GET_SCANLINE(45h): 00 (0b0)
GET_DISPLAY_BRIGHTNESS(52h): 00 (0b0)
GET_CONTROL_DISPLAY(54h): 00 (0b0)
GET_POWER_SAVE(56h): 00 (0b0)
GET_CABC_MIN_BRIGHTNESS(5Fh): 00 (0b0)
READ_DDB_START(A1h): 00 (0b0)
READ_DDB_CONTINUE(A8h): 00 (0b0)

regmap

Regmap isn't currently used in tinydrm, but might be used as a way to represent a LCD register.

Event tracing can be used see what's been written to the registers:

#enable
echo 1 | sudo tee /sys/kernel/debug/tracing/events/regmap/regmap_reg_write/enable
echo 1 | sudo tee /sys/kernel/debug/tracing/events/regmap/regmap_reg_read/enable

#disable
echo | sudo tee /sys/kernel/debug/tracing/set_event

#start
echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on

#stop
echo 0 | sudo tee /sys/kernel/debug/tracing/tracing_on

#view
sudo cat /sys/kernel/debug/tracing/trace

#clear
echo | sudo tee /sys/kernel/debug/tracing/trace

Platform data

tinydrm doesn't support platform data, but it's still possible use it without Device Tree. This example is taken from my work on fb_ili9325.

#include <linux/gpio/machine.h>
#include <linux/property.h>
#include <linux/spi/spi.h>

static const struct spi_board_info hy28a = {
	.modalias = "fb_ili9320",
	.max_speed_hz = 32000000,
	.bus_num = 0,
	.chip_select = 0,
	.mode = SPI_MODE_3,
};

static struct property_entry hy28a_properties[] = {
	PROPERTY_ENTRY_BOOL("bgr"),
	PROPERTY_ENTRY_U32("rotation", 270),
	{ },
};

static struct gpiod_lookup_table hy28a_gpios = {
	.dev_id = "spi0.0",
	.table = {
		GPIO_LOOKUP("pinctrl-bcm2835", 25, "reset", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("pinctrl-bcm2835", 18, "led", GPIO_ACTIVE_LOW),
		{ },
	},
};

static int bus_notifier_call(struct notifier_block *n, unsigned long action, void *data)
{
	struct device *dev = data;

	if (action == BUS_NOTIFY_ADD_DEVICE) {
		if (!strcmp(dev_name(dev), "spi0.0")) {
			dev_info(dev, "hy28a registered\n");
			device_add_properties(dev, hy28a_properties);
		}
	}

	return NOTIFY_DONE;
}

static struct notifier_block bus_notifier = {
	.notifier_call = bus_notifier_call,
};

static int __init hy28a_register(void)
{
	int ret;

	gpiod_add_lookup_table(&hy28a_gpios);

	bus_register_notifier(&spi_bus_type, &bus_notifier);
	ret = spi_register_board_info(&hy28a, 1);
	if (ret) {
		pr_err("Failed to register hy28a\n");
		return ret;
	}

	return 0;
}

gpiod_add_lookup_table() isn't exported so this can't be done from a loadable module.

Clone this wiki locally