LINUX.ORG.RU

Непонятное поведение mmap()

 ,


0

2

Здравствуйте.

Одноплатная система на SOC AllWinner V3s (Cortex A7). Ранее использовалось ядро 4.13-rc2 . По ряду причин пришлось перейти на 5.14.11.

В linux используется графический драйвер SimpleFB, которому загручик передает параметры и адрес в памяти фреймбуфера. Видеоконтроллер (TCON) заранее настраивается в загрузчике, поэтому доступ в регистры TCON для SimpleFB не нужен. В user space написан драйвер для регулировки гамма-коррекции дисплея. Драйвер получает виртуальные адреса регистров TCON через mmap и осуществляет запись значений гаммы в соответствующие регистры.

После перехода на 5.14 драйвер перестал работать. То есть, mmap-ится без ошибок, но от записи значений нулевой эффект.

Я не поленился, и сляпал драйвер ядра, в котором виртуальные адреса регистров получаются через ioremap. Эффект от записи значений в адреса, что через writel(), что напрямую, тот же, то есть, нулевой. Получение адресов через devm_regmap_init_mmio() и запись регистров вызовом regmap_write() проблемы также не решает.

В системе есть мой драйвер ядра для специализированного RS-485. Драйвер также использует запись в регистры UART и управления GPIO. Адреса регистров получаются через ioremap. Но этот драйвер работает в 5.14 без проблем.

Куда копать? В чем злое колдунство?

Физические адреса начала диапазонов регистров:

GPIO: 0x01C20800 UART: 0x01C28000 TCON: 0x01C0C000


Через devmem2 (или т.п.) пробовал вручную выставлять регистры?

AlexVR ★★★★★
()

Под рукой только t113s3. Ядро Mainline 6.6 из Yocto.

Базовый адрес другой 0x05461000

Сравнил даташиты. Описания регистров в этом случае аналогичные. В регистре TCON_GCTL_REG (LCD_GCTL_REG +0x0000) два бита. Gamma (30-й предпоследний бит) отключена по умолчанию. В таблице мусор (+0x0400).

# devmem2 0x5461000 w
/dev/mem opened.
Memory mapped at address 0xb6f5c000.
Read at address  0x05461000 (0xb6f5c000): 0x80000000

Включаю гамма коррекцию:

devmem2 0x5461000 w 0xc0000000

Ожидаемый жбан с цветами на экране.

Выключаю:

devmem2 0x5461000 w 0x80000000
AlexVR ★★★★★
()

Эффект от записи значений в адреса, что через writel(), что напрямую, тот же, то есть, нулевой.

Поигрался с этой гамма коррекцией. Для установки надо:

  1. Открыть /dev/mem.
  2. Сделать mmap.
  3. Отключить коррекцию в TCON_GCTL_REG.
  4. Записать таблицу.
  5. Включить коррекцию в TCON_GCTL_REG.

Без 3 и 5 изменения не применяются.

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

Посмотрел исходник devmem2. Никаких отличий в использовании mmap от моего user space драйвера я не увидел. Можно, конечно собрать, испытать для очистки совести.

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

Так в моем драйвере и сделано.

Заостряю внимание: один и тот же код с ядром 4.13 работает, а с 5.14 нет.

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

один и тот же код с ядром 4.13 работает, а с 5.14 нет.

При этом я так же указал на каком ядре и камне тестировал.

Ранее использовалось ядро 4.13-rc2 . По ряду причин пришлось перейти на 5.14.11.

Это какие-то странные версии. Так понимаю недоядра от Allwinner? Тут момент, что с этим китайским SDK можно столько CVE получить… Так что я предпочитаю поддерживать актуальные версии buildroot/yocto. Хоть и путём таскания пачки патчей.

Так в моем драйвере и сделано.

Код я не вижу. И первое, что попало под руку, это необходимость дёрнуть бит. Тем более что не было раскрыто значение фразы:

но от записи значений нулевой эффект.

Это нет визуального эффекта? Или регистры не меняются?

Точного ответа тебе мало вероятно кто даст. Не код, не параметры сборки не видит никто кроме тебя. А число людей занимающихся такими микропроцессорами… Да ещё и с выходом за пределы реализованного функционала в типовых сборках (гамма коррекция для Allwinner в Mainline представлена одним RFC патчем, а аллвиноровский fex - это отдельная история).

Так что остаётся только гадать.

Что ещё в голову пришло: смотрю кусок кода из текущего dts в Mainline Linux

		tcon0: lcd-controller@1c0c000 {
			compatible = "allwinner,sun8i-v3s-tcon";
			reg = <0x01c0c000 0x1000>;
			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&ccu CLK_BUS_TCON0>,
				 <&ccu CLK_TCON0>;
			clock-names = "ahb",
				      "tcon-ch0";
			clock-output-names = "tcon-data-clock";
			#clock-cells = <0>;
			resets = <&ccu RST_BUS_TCON0>;
...

Тут пачка связанных прерываний, клоков и т.п. Добавим:

Видеоконтроллер (TCON) заранее настраивается в загрузчике, поэтому доступ в регистры TCON для SimpleFB не нужен.

В загрузчике это всё может и было настроено. НО!!! где гарантия, что что-то из этого не деактивировано ядром? Так что проверь регистры связанных устройст.

У меня экран полноценно описан в dts и им полноценно управляет ядро.

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

Ранее использовалось ядро 4.13-rc2 . По ряду причин пришлось перейти на 5.14.11. Это какие-то странные версии. Так понимаю недоядра от Allwinner?

Ядро ванильное. Необходимые драйверы патчил вручную сам.

Так в моем драйвере и сделано. Код я не вижу.

Код тривиален.

но от записи значений нулевой эффект. Это нет визуального эффекта?

Именно так. Бинарник приложения, правильно работающий из-под 4.13 , запущенный в 5.14 в этом месте (регулировка гаммы) не работает.

Или регистры не меняются?

Кстати, при чтении регистров TCON читаются только нули.

Точного ответа тебе мало вероятно кто даст.

Вероятно. Но, к примеру, начиная с 5 версии ядра была убрана функция ioremap_nocache().

Не код, не параметры сборки не видит никто кроме тебя.

И по поводу параметров.

В конфигах ядер 4 и 5 в настройках управления памятью имеются различия. То есть, параметры имеющиеся в 4.x отсутствуют в 5.x и наоборот. А некоторые параметры, к примеру

ARCH_SELECT_MEMORY_MODEL

имеют в конфигах моих сборок разные значения, но не доступны для изменения через linux-menuconfig.

Многие исходники из /arch/arm/mm/ то есть драйверы, управляющие MMU и ремапами, отличаются между ядрами, и довольно сильно, по размерам.

Изменений в этой части ядра между 4 и 5 изрядно.

Есть подозрение, что собака порылась где-то здесь.

Что ещё в голову пришло: смотрю кусок кода из текущего dts в Mainline Linux

Убирал в своем dts из этой секции свойство "reg = ". Эффекта ноль. Но это уже судороги.

Видеоконтроллер (TCON) заранее настраивается в загрузчике, поэтому доступ в регистры TCON для SimpleFB не нужен. В загрузчике это всё может и было настроено. НО!!! где гарантия, что что-то из этого не деактивировано ядром? Так что проверь регистры связанных устройст.

Это как ? Ядро ни с того ни с сего вдруг пишет именно в этот диапазон адресов значения (какие и зачем)?

Видеоконтроллер, если что, работает. Изображение есть.

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

Это как ?

К примеру (только к примеру):

			clocks = <&ccu CLK_BUS_TCON0>,
				 <&ccu CLK_TCON0>;

Не используются, и отключаются драйвером allwinner,sun8i-v3s-ccu.

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

Видеоконтроллер, если что, работает. Изображение есть.

Кстати, при чтении регистров TCON читаются только нули.

Драйвер также использует запись в регистры UART и управления GPIO. Адреса регистров получаются через ioremap. Но этот драйвер работает в 5.14 без проблем.

Больше похоже, что модуль видеоконтроллера работает не корректно. А то тут работает, тут нет.

AlexVR ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.