관련자료

Vanilla 커널사용 시 필요한 패치(5.10, 5.12버전 기준)

  • 재부팅 문제 수정 (참고 소스)
    drivers/gpu/drm/meson/meson-drv.c 파일의 platform_driver 구조체 변수 선언에서 shutdown 함수 할당 주석 또는 제거 (적용 후에도 간혹 재부팅 안되는 경우가 있음, 5.10버전대는 meson_drv.c 파일)
static struct platform_driver meson_drm_platform_driver = {
	.probe      = meson_drv_probe,
/*	.shutdown   = meson_drv_shutdown, */
	.driver     = {
		.name	= "meson-drm",
		.of_match_table = dt_match,
		.pm = &meson_drv_pm_ops,
	},
};
  • Makefile(drivers/pwm) 적용
...
obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM)	+= pwm-fsl-ftm.o
obj-$(CONFIG_PWM_GPIO)		+= pwm-gpio.o
obj-$(CONFIG_PWM_HIBVT)		+= pwm-hibvt.o
obj-$(CONFIG_PWM_IMG)		+= pwm-img.o
...
  • Kconfig(drivers/pwm) 적용
...
	  To compile this driver as a module, choose M here: the module
	  will be called pwm-fsl-ftm.

config PWM_GPIO
	tristate "Generic GPIO bit-banged PWM driver"
	depends on OF
	depends on GPIOLIB
	help
	  Some platforms do not offer any hardware PWM capabilities but do have
	  General Purpose Input Output (GPIO) pins available. Using the kernels
	  High-Resolution Timer API this driver tries to toggle GPIO using the
	  generic kernel PWM framework. The maximum frequency and/or accuracy
	  is dependent on several factors such as system load and the maximum
	  speed a pin can be toggled at the hardware.

	  To compile this driver as a module, choose M here: the module
	  will be called pwm-gpio.

config PWM_HIBVT
	tristate "HiSilicon BVT PWM support"
	depends on ARCH_HISI || COMPILE_TEST
	depends on HAS_IOMEM
...
  • Device Tree 적용
    arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
...
#include <dt-bindings/sound/meson-g12a-toacodec.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
#include <dt-bindings/pwm/pwm.h>
...

/ {
...
	pwmgpio:pwmgpio {
		compatible = "pwm-gpio";
		#pwm-cells = <3>;
		pwm-gpios = <&gpio_ao GPIOAO_10 GPIO_ACTIVE_HIGH>;
		status = "okay";
	};

	pwmfan:pwm-fan {
		compatible = "pwm-fan";
		pwms = <&pwmgpio 0 40000 PWM_POLARITY_INVERTED>;
		cooling-min-state = <0>;
		cooling-max-state = <3>;
		#cooling-cells = <2>;
		cooling-levels = <0 120 170 220>;
	};
};

&cpu_thermal {
	trips {
		fan_0: trip-point@4 {
			temperature = <45000>;
			hysteresis = <5000>;
			type = "active";
		};
		fan_1: trip-point@5 {
			temperature = <65000>;
			hysteresis = <5000>;
			type = "active";
		};
		fan_2: trip-point@6 {
			temperature = <75000>;
			hysteresis = <5000>;
			type = "active";
		};
	};
	cooling-maps {
		fan_cooling_map0 {
			trip = <&fan_0>;
			cooling-device = <&pwmfan 0 1>;
		};
		fan_cooling_map1 {
			trip = <&fan_1>;
			cooling-device = <&pwmfan 1 2>;
		};
		fan_cooling_map2 {
			trip = <&fan_2>;
			cooling-device = <&pwmfan 2 3>;
		};
	};
};

...
  • Makefile(drivers/char) 적용
...
obj-$(CONFIG_XILLYBUS)		+= xillybus/
obj-$(CONFIG_POWERNV_OP_PANEL)	+= powernv-op-panel.o
obj-$(CONFIG_ADI)		+= adi.o

obj-$(CONFIG_AMLOGIC_GPIOMEM)	+= aml-gpiomem.o
  • Kconfig(drivers/char) 적용
...
	  and SSM (Silicon Secured Memory).  Intended consumers of this
	  driver include crash and makedumpfile.

config AMLOGIC_GPIOMEM
	tristate "/dev/gpiomem rootless GPIO access via mmap() on the Amlogic"
	default m
	help
	  Provides users with root-free access to the GPIO registers
	  on Meson g12 platform. Calling mmap(/dev/gpiomem) will map the GPIO
	  register page to the user's pointer. This drvier can allow to access
	  gpio memory area in user account.

endmenu
...
  • Device Tree 적용
    arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
    (compatible 문자열에 공백을 제거하고싶다면 drivers/char/aml-gpiomem.c의 compatible 정의도 마찬가지로 공백을 제거해야 함)
/ {
...
	gpiomem {
		compatible = "amlogic, gpiomem";
		reg = <0x0 0xff634000 0x0 0x1000>;
		status = "okay";
	};
};
  • I2C-0 활성
  • Device Tree 적용
    arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
    pinctrl 이름은 drivers/pinctrl/meson/pinctrl-meson-g12a.c 파일에서 참조
    GPIO PINMAP은 하드커널 위키에서 참조
/ {
...
};

&i2c2 {
	status = "okay";
	pinctrl-0 = <&i2c2_sda_x_pins>, <&i2c2_sck_x_pins>;
	pinctrl-names = "default";
};

...
  • I2C-1 활성
  • Device Tree 적용
    arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
/ {
...
};

&i2c3 {
	status = "okay";
	pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
	pinctrl-names = "default";

	/* rtc를 사용할 때 아래 블록 함께 추가 */
	pcf8563: rtc@51 {
		compatible = "nxp,pcf8563";
		reg = <0x51>;
	};
};

...
  • SPIDEV0.0 활성
  • Device Tree 적용
/ {
...
};

&spicc0 {
	status = "okay";

	#address-cells = <1>;
	#size-cells = <0>;

	pinctrl-names = "default";
	pinctrl-0 = <&spicc0_x_pins &spicc0_ss0_x_pins>;
	cs-gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>;

	spidev: spidev@0 {
		status = "okay";
		compatible = "linux,spidev";
		reg = <0>;
		/* spi default max clock 100Mhz */
		spi-max-frequency = <10000000>;
	};
};

...
  • GPIO PWM CD, EF 채널 추가
  • Device Tree 적용 (참고내용)
    arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
    sysfs 경로는 ls -al /sys/class/pwm/pwmchip*/device 명령을 실행하여 링크가 ffd1a000.pwm면 CE, ffd19000.pwm면 EF 핀의 pwmchip
/ {
...
};

&periphs_pinctrl {
	pwmcd_to_gpios: pwmcd_gpio {
		mux {
			groups = "GPIOX_5", "GPIOX_6";
			function = "gpio_periphs";
		};
	};

	pwmef_to_gpios: pwmef_gpio {
		mux {
			groups = "GPIOX_16", "GPIOX_7";
			function = "gpio_periphs";
		};
	};
};

&pwm_cd {
	status = "okay";
	clocks = <&xtal>, <&xtal>, <&xtal>, <&xtal>;
	clock-names = "clkin0", "clkin1", "clkin2", "clkin3";

	pinctrl-names = "default";
	pinctrl-0 = <&pwm_c_x5_pins &pwm_d_x6_pins>;
	pinctrl-1 = <&pwmcd_to_gpios>;
};

&pwm_ef {
	status = "okay";
	clocks = <&xtal>, <&xtal>, <&xtal>, <&xtal>;
	clock-names = "clkin0", "clkin1", "clkin2", "clkin3";

	pinctrl-names = "default";
	pinctrl-0 = <&pwm_e_pins &pwm_f_x_pins>;
	pinctrl-1 = <&pwmef_to_gpios>;
};

...

해결이 필요한 문제

  • Prebuild OS (Ubuntu 10.04)
    • PWM-FAN이 45도 이상 온도에서도 동작하지 않음 (원인을 잘 모르겠음)
    • btrfs를 사용할 수 없음 (마운트하면 커널 패닉)
  • Vanilla Kernel
    • sysfs GPIO(/sys/class/gpio)가 동작하지 않음 (대신 hardkernel 커널에 포팅 된 gpiomem을 사용)
    • GPU 하드웨어 가속 드라이버(panfrost)가 X11에서 영상 디코딩 레이어, 마우스 포인터 렌더링에 문제가 있음
    • 프로세서 로드가 높을 때 IO가 많이 일어나면 커널 패닉이 일어나는 일이 많음

해결이 안될거같은 문제

  • SPI 인터페이스와 GPIO 동시 사용 시 SPI에 간섭이 생겨 SPI 데이터가 손상되는 문제 발생
    SPI 드라이버가 DMA 방식이 아닌 PIO 모드로 구현된것이 원인일 것으로 예상(참조: spi meson 코드), 라즈베리파이에서는 간섭이 일어나지 않으므로 SPI와 GPIO를 동시에 사용한다면 프로세서의 성능차이가 커도 라즈베리파이를 사용하거나 라즈베리파이 피코, 아두이노같은 장치를 함께 사용해야 하는 단점이 발생 (예로 IR 신호를 송신하면 SPI 디스플레이 화면이 잠깐 일그러지며 SPI 디스플레이에 제어신호 전송 시 SPI 데이터가 손상되면 제어코드가 잘못 전송되어 표현에 문제가 생기는 현상도 발생)
  • SPI 인터페이스의 데이터 전송속도 문제
    • Vanilla Kernel 기준, 약 115kb 전송에 걸리는 시간
      bits per word를 8로 설정: 약 0.143초 (~800kb/s)
      bits per word를 32로 설정: 약 0.096초 (~1,200kb/s)
      하드커널에서 재공하는 커널은 bits per word를 64로 사용가능한것으로 보이지만 현재 사용하는 커널은 Vanilla Kernel이고 bits per word를 64로 설정하지 못하므로 나중에 기회되면 확인필요 (소스코드, 포럼 글)
    • 라즈베리파이 3B+ 기준, 약 115kb 동일 데이터 전송에 걸리는 시간
      bits per word를 8로 설정: 약 0.045초 (~2,555kb/s)
      16, 32 둘 다 설정이 불가능하여 확인불가 (이미 압도적으로 빠르다)
    • 결과적으로 240×240 해상도의 SPI 인터페이스 LCD를 연결할경우 라즈베리파이는 34~35프레임으로 부드러워 보이지만 오드로이드는 9~10프레임으로 부드러운 애니메이션 표현이 불가능

기타

  • sdcard로 이미지 쓰기 시 progress 정상표시 (olfsg=dsync)
    dd if=sdcard.img of=/dev/sdX bs=1M oflag=dsync status=progress
  • 5.11.22버전 부터는 End-of-Life로 분류되어 5.10버전과 5.12버전 기준으로 내용 변경
  • EGL_PLATFORM_GBM_KHR으로 생성한 EGL 인터페이스로 off screen 렌더링을 수행 시 프래임마다 glFlush()를 호출하지않으면 메모리 사용량이 계속 늘어남(GL 인터페이스 규격 사항 때문으로 보임)

사용중인 환경

  • 리눅스 배포본: 젠투리눅스
  • 파일시스템: zfs
  • Kernel Config: (아래 첨부)

2021-10-23 현재 커널버전 5.14.13까지 vanilla 커널을 사용을 끝으로 커널 패닉을 감당하기 힘들어 하드커널에서 배포하는 커널로 복귀. 2021버전으로 빌드하여 사용한 u-boot의 차이인지 어디에서 문제인지 확인이 불가능.

기왕 최신 커널을 포기한거 그냥 ASUS의 Tinker Board 2나 Tinker Board 2S로 눈 돌릴까 생각이 든다. 애초 SPI 드라이버가 DMA 방식을 사용하지 않아서 그런지 GPIO에 간섭받는 문제있고 CPU의 처리 속도차이는 어느정도인지 몰라도 3D 가속 능력은 그리 중요하지 않아서 N2의 GPU가 더 최신 아키텍처이지만 별 의미가 없어보인다. (USB-C 모니터를 쓸 수 있는건 덤) 프로그래밍을 끝낸 지금은 SPI 성능이 훨씬 좋은 라즈베리파이로 옮겨서 사용중이지만 나중에 다시 SPI 인터페이스로 프로그래밍을 하게되면 Tinker Board 구입을 다시 생각 해 봐야겠다.