LINUX.ORG.RU

fbset не меняет bpp

 


0

1

Добрый день!

Имеется плата stm32mp157 с Линуксом на борту, цепляю к ней через spi OLED ssd1306. Во время загрузки на экране моргает курсор, после окончания загрузки экран заливается белым цветом, вывести на него ничего нельзя, но на вкл. выкл. реагирует.

fbset -i -v выдает:

root@ATK-MP157:~# fbset -i -v
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'

mode "128x64"
    geometry 128 64 128 64 16
    timings 0 0 0 0 0 0 0
    nonstd 1
    rgba 5/11,6/5,5/0,0/0
endmode

Getting further frame buffer information
Frame buffer device information:
    Name        : fb_ssd1306
    Address     : (nil)
    Size        : 16384
    Type        : PACKED PIXELS
    Visual      : TRUECOLOR
    XPanStep    : 0
    YPanStep    : 0
    YWrapStep   : 0
    LineLength  : 256
    Accelerator : No

Очевидно, что драйвер проинициализирован левыми данными, как bpp = 16 (должен быть 1), rgba 5/11,6/5,5/0,0/0 (1/0, 1/0, 1/0, 0/0).

fbset -depth 1 ничего не меняет, так же как и fbset -g 128 64 128 64 1.

На /etc/fb.modes тоже болт забивается. Подскажите, пожалуйста, в чем проблема?

Ради эксперемента, попробуй в драйвере в функции замени аргумент preferred_bpp с 16 на 1. Хотя врядли сработает

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 411103f013e2..27cb4ded1239 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -197,7 +197,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
        if (ret)
                goto err_put;
 
-       drm_fbdev_generic_setup(ddev, 16);
+       drm_fbdev_generic_setup(ddev, 1);
 
        return 0;

Обычно bpp это принимает значения 8, 16, 24, 32. spi OLED ssd1306 это какой маленький дисплей - монохронный ? Надо смотреть есть драйвер в ядре для него, включен ли он в config ядра, надо ли его конфигурировать в device tree.

guskov_roman
()
Ответ на: комментарий от guskov_roman

OLED монохромный. Драйвер есть, включен. Если задавать bpp через device tree, то драйвер фреймбуфера игнорирует этот параметр, устанавливает его в 16, если же bpp = 1 прописать в структуре display драйвера OLED, то параметр передается в драйвер фреймбуфера, но при этом ядро падает на записи в память.

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

А какой драйвер ты используешь ? В ядре есть два драйвера drivers/video/fbdev/ssd1307fb.c и drivers/staging/fbtft/fb_ssd1306.c

Первый управляеться через i2c, тот который staging управляеться через spi и через i2c работать не будет. Но ssd1307fb.c потдерживает и ssd1306fb-i2c.

Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml

В указаном выше тренде как раз эта проблема обсуждалась. Посмотри, может у тебя драйвер не тот ?

guskov_roman
()

Через опции ядра разрешение и глубину цвета задавать надо. fbset уже в 2006-м году не работал. Многое поменялось.

saahriktu ★★★★★
()
Ответ на: комментарий от guskov_roman

А какой драйвер ты используешь ?

drivers/staging/fbtft/fb_ssd1306.c

Во время загрузки появляется моргающий курсор, след драйвер и железо работает.

AlexVM2020
() автор топика
Ответ на: комментарий от saahriktu

В конфиге загрузчика (того же GRUB’а, например). Там есть строка > с опциями ядра.

Какой еще grub, у него stm32mp1 - там U-Boot. В новых ядрах ничего не надо для графики передевать через bootarg.

guskov_roman
()
Ответ на: комментарий от AlexVM2020

Во время загрузки появляется моргающий курсор, след драйвер и > железо работает.

Не факт что он работает. Он загрузился, но потом он должен железку инициализировать и подготовить к работе. Видимо этого не произошло и тебе нужен другой драйвер, который работает через i2c. Через menuconfig включи драйвер Solomon SSD1307 и перекомпилируй ядро. По умолчанию он выключен.

-> Device Drivers                                                                                                                                                           
   -> Graphics support                                                                                                                                                           
      -> Frame buffer Devices
         -> Support for frame buffer devices
            -> Solomon SSD1307 framebuffer support
guskov_roman
()
Ответ на: комментарий от guskov_roman

Ядерная консоль берёт параметры разрешения и глубины цвета из аргументов ядра. В иксах или Wayland'е, конечно, всё может работать и без дополнительных аргументов.

saahriktu ★★★★★
()
Ответ на: комментарий от saahriktu

Я понимаю о чем ты говоришь, но это не наш случай. Тут совсем простой драйвер - на 800 строк кода, он такого не умеет.

guskov_roman
()
Ответ на: комментарий от guskov_roman

Не факт что он работает. Он загрузился, но потом он должен железку инициализировать и подготовить к работе. Видимо этого не произошло и тебе нужен другой драйвер, который работает через i2c.

Если честно, не понимаю, зачем включать драйвер для I2C, если у меня жки по SPI работает?

При отладке обнаружилось две проблемы.

  1. В драйвер fbtft не передавался параметр txbuflen, и драйвер ЖКИ пытался выводить данные в пустоту. Никаких проверок этого момента нигде не предусмотрено.

  2. Размер виртуальной памяти под экран в драйвере fdtft вычисляется как

vmem_size = display->width * display->height * bpp / 8;

vmem = vzalloc(vmem_size);

info->screen_buffer = vmem;

в моем случае 128 * 64 * 1 / 8 = 1024 байта,

а в драйвере жки при копировании из вирт памяти в передающий буфер

u16 *vmem16 = (u16 *)par->info->screen_buffer;

for (x = 0; x < xres; x++) {
		for (y = 0; y < yres / 8; y++) {
			*buf = 0x00;
			for (i = 0; i < 8; i++)
				if (vmem16[(y * 8 + i) * xres + x])
					*buf |= BIT(i);
			buf++;
		}
	}

в строке if (vmem16[(y * 8 + i) * xres + x]) при некотором y происходит обращение к вирт памяти за пределами 1024 байта. Опять какой-то непонятный косяк.

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

То есть получается. что для вирт экрана и для ЖКИ разные bpp надо задавать?

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

Если честно, не понимаю, зачем включать драйвер для I2C, если у меня жки по SPI работает?

Ну ты ж не писал нигде что он у тебя через spi работает.

Но вообще у драйвера drivers/staging/fbtft/fb_ssd1306.c последний коммит от марта 2019 года и он выглядит заброшеным. И скорее всего на совместимость с новыми ядрами его никто особо не тестировал. А fb с тех пор много чего поменялось. А вот драйвер drivers/video/fbdev/ssd1307fb.c вполне живой. Так что либо использовать новый драйвер, либо откатить ядро до какого нибудь 4.19 или даже старше и пробовать - а вдруг заработатет. Ну есть еще путь для настоящих джедаев - переписать драйвер самому и протащить его в mainline ядро.

Вообще такое встречается не так уж и редко. Я как то наткнулся на баг для той же stm32mp15 в spi драйвере. Писал им багрепорты - ноль реакции. Мне это надоело, я пофиксил баг и отправил его в ядро и его приняли. Только после этого stm зашевелились и пофиксили сами. Меня они еще (по ошибке видимо) добавили меня в CC и мне на почту начала валится вся переписка разработчиков с руганью.

А коммит мой с тех так и остался в ядре.

guskov_roman
()
Последнее исправление: guskov_roman (всего исправлений: 2)
Ответ на: комментарий от guskov_roman

Думаю, проще всего в drivers/video/fbdev/ssd1307fb.c добавить поддержку spi и закрыть вопрос. Спасиб за помошь.

AlexVM2020
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.