요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
================================================
SH7760/SH7763 integrated LCDC Framebuffer driver
================================================
0. Overview
-----------
The SH7760/SH7763 have an integrated LCD Display controller (LCDC) which
supports (in theory) resolutions ranging from 1x1 to 1024x1024,
with color depths ranging from 1 to 16 bits, on STN, DSTN and TFT Panels.
Caveats:
* Framebuffer memory must be a large chunk allocated at the top
of Area3 (HW requirement). Because of this requirement you should NOT
make the driver a module since at runtime it may become impossible to
get a large enough contiguous chunk of memory.
* The driver does not support changing resolution while loaded
(displays aren't hotpluggable anyway)
* Heavy flickering may be observed
a) if you're using 15/16bit color modes at >= 640x480 px resolutions,
b) during PCMCIA (or any other slow bus) activity.
* Rotation works only 90degress clockwise, and only if horizontal
resolution is <= 320 pixels.
Files:
- drivers/video/sh7760fb.c
- include/asm-sh/sh7760fb.h
- Documentation/fb/sh7760fb.rst
1. Platform setup
-----------------
SH7760:
Video data is fetched via the DMABRG DMA engine, so you have to
configure the SH DMAC for DMABRG mode (write 0x94808080 to the
DMARSRA register somewhere at boot).
PFC registers PCCR and PCDR must be set to peripheral mode.
(write zeros to both).
The driver does NOT do the above for you since board setup is, well, job
of the board setup code.
2. Panel definitions
--------------------
The LCDC must explicitly be told about the type of LCD panel
attached. Data must be wrapped in a "struct sh7760fb_platdata" and
passed to the driver as platform_data.
Suggest you take a closer look at the SH7760 Manual, Section 30.
(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf)
The following code illustrates what needs to be done to
get the framebuffer working on a 640x480 TFT::
#include <linux/fb.h>
#include <asm/sh7760fb.h>
/*
* NEC NL6440bc26-01 640x480 TFT
* dotclock 25175 kHz
* Xres 640 Yres 480
* Htotal 800 Vtotal 525
* HsynStart 656 VsynStart 490
* HsynLenn 30 VsynLenn 2
*
* The linux framebuffer layer does not use the syncstart/synclen
* values but right/left/upper/lower margin values. The comments
* for the x_margin explain how to calculate those from given
* panel sync timings.
*/
static struct fb_videomode nl6448bc26 = {
.name = "NL6448BC26",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39683, /* in picoseconds! */
.hsync_len = 30,
.vsync_len = 2,
.left_margin = 114, /* HTOT - (HSYNSLEN + HSYNSTART) */
.right_margin = 16, /* HSYNSTART - XRES */
.upper_margin = 33, /* VTOT - (VSYNLEN + VSYNSTART) */
.lower_margin = 10, /* VSYNSTART - YRES */
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,
};
static struct sh7760fb_platdata sh7760fb_nl6448 = {
.def_mode = &nl6448bc26,
.ldmtr = LDMTR_TFT_COLOR_16, /* 16bit TFT panel */
.lddfr = LDDFR_8BPP, /* we want 8bit output */
.ldpmmr = 0x0070,
.ldpspr = 0x0500,
.ldaclnr = 0,
.ldickr = LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
LDICKR_CLKDIV(1),
.rotate = 0,
.novsync = 1,
.blank = NULL,
};
/* SH7760:
* 0xFE300800: 256 * 4byte xRGB palette ram
* 0xFE300C00: 42 bytes ctrl registers
*/
static struct resource sh7760_lcdc_res[] = {
[0] = {
.start = 0xFE300800,
.end = 0xFE300CFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 65,
.end = 65,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sh7760_lcdc_dev = {
.dev = {
.platform_data = &sh7760fb_nl6448,
},
.name = "sh7760-lcdc",
.id = -1,
.resource = sh7760_lcdc_res,
.num_resources = ARRAY_SIZE(sh7760_lcdc_res),
};
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
LCDC 기능과 하드웨어 제약
1-32SH7760/SH7763에는 LCD Display Controller(LCDC)가 통합되어 있습니다. 이론상 STN, DSTN, TFT 패널에서 1x1부터 1024x1024까지의 해상도와 1~16비트 색 깊이를 지원합니다.
framebuffer 메모리는 하드웨어 요구 때문에 Area3 최상단에 큰 연속 덩어리로 할당해야 합니다. 실행 중에는 충분히 큰 연속 메모리를 얻지 못할 수 있으므로 드라이버를 모듈로 만들면 안 됩니다. 로드된 동안 해상도 변경도 지원하지 않으며, 어차피 디스플레이는 hotplug 대상이 아닙니다.
640x480 이상에서 15/16비트 색 모드를 사용하거나 PCMCIA 등 느린 버스가 동작하면 심한 깜박임이 생길 수 있습니다. 회전은 가로 해상도가 320픽셀 이하일 때 시계 방향 90도만 지원합니다.
관련 파일은 `drivers/video/sh7760fb.c`, `include/asm-sh/sh7760fb.h`, `Documentation/fb/sh7760fb.rst`입니다.
================================================
SH7760/SH7763 integrated LCDC Framebuffer driver
================================================
0. Overview
-----------
The SH7760/SH7763 have an integrated LCD Display controller (LCDC) which
supports (in theory) resolutions ranging from 1x1 to 1024x1024,
with color depths ranging from 1 to 16 bits, on STN, DSTN and TFT Panels.
Caveats:
* Framebuffer memory must be a large chunk allocated at the top
of Area3 (HW requirement). Because of this requirement you should NOT
make the driver a module since at runtime it may become impossible to
get a large enough contiguous chunk of memory.
* The driver does not support changing resolution while loaded
(displays aren't hotpluggable anyway)
* Heavy flickering may be observed
a) if you're using 15/16bit color modes at >= 640x480 px resolutions,
b) during PCMCIA (or any other slow bus) activity.
* Rotation works only 90degress clockwise, and only if horizontal
resolution is <= 320 pixels.
Files:
- drivers/video/sh7760fb.c
- include/asm-sh/sh7760fb.h
- Documentation/fb/sh7760fb.rst
플랫폼 초기화와 패널 정의
33-54SH7760은 DMABRG DMA 엔진으로 비디오 데이터를 가져옵니다. 따라서 부팅 중 `DMARSRA` 레지스터에 `0x94808080`을 써서 SH DMAC를 DMABRG 모드로 구성해야 합니다. PFC 레지스터 `PCCR`과 `PCDR`에는 모두 0을 써서 peripheral mode로 설정해야 합니다.
드라이버는 이 보드 초기화를 대신 수행하지 않습니다. 해당 처리는 board setup code의 책임입니다.
LCDC에는 연결된 LCD 패널 종류를 명시적으로 알려야 합니다. 데이터는 `struct sh7760fb_platdata`로 감싸 `platform_data`로 드라이버에 전달합니다. 세부 사항은 SH7760 Manual Section 30과 `http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf`를 참고합니다.
드라이버 등록 전에 보드 코드가 준비해야 하는 항목입니다.
1. Platform setup
-----------------
SH7760:
Video data is fetched via the DMABRG DMA engine, so you have to
configure the SH DMAC for DMABRG mode (write 0x94808080 to the
DMARSRA register somewhere at boot).
PFC registers PCCR and PCDR must be set to peripheral mode.
(write zeros to both).
The driver does NOT do the above for you since board setup is, well, job
of the board setup code.
2. Panel definitions
--------------------
The LCDC must explicitly be told about the type of LCD panel
attached. Data must be wrapped in a "struct sh7760fb_platdata" and
passed to the driver as platform_data.
Suggest you take a closer look at the SH7760 Manual, Section 30.
(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf)
640x480 TFT 모드와 platform data
55-103예제는 NEC NL6440bc26-01 640x480 TFT를 25,175 kHz dot clock으로 구동합니다. X/Y 해상도는 640x480, 전체 주기는 800x525, sync 시작은 656/490, sync 길이는 30/2입니다.
Linux framebuffer 계층은 syncstart/synclen 대신 오른쪽·왼쪽·위·아래 margin을 사용합니다. 따라서 `.left_margin = 114`는 `HTOT - (HSYNSLEN + HSYNSTART)`, `.right_margin = 16`은 `HSYNSTART - XRES`, `.upper_margin = 33`은 `VTOT - (VSYNLEN + VSYNSTART)`, `.lower_margin = 10`은 `VSYNSTART - YRES`로 계산합니다.
`struct fb_videomode nl6448bc26`은 60 Hz, 640x480, `pixclock = 39683` ps, 수평/수직 sync 길이 30/2, high-active sync, non-interlaced를 지정합니다.
`struct sh7760fb_platdata sh7760fb_nl6448`는 이 모드를 기본값으로 가리키고 `LDMTR_TFT_COLOR_16` 16비트 TFT 패널, `LDDFR_8BPP` 8비트 출력, `ldpmmr = 0x0070`, `ldpspr = 0x0500`, `ldaclnr = 0`을 설정합니다. LCDC 외부 clock을 divider 1로 쓰며, 회전은 0, `novsync`는 1, `blank` 콜백은 `NULL`입니다.
The following code illustrates what needs to be done to
get the framebuffer working on a 640x480 TFT::
#include <linux/fb.h>
#include <asm/sh7760fb.h>
/*
* NEC NL6440bc26-01 640x480 TFT
* dotclock 25175 kHz
* Xres 640 Yres 480
* Htotal 800 Vtotal 525
* HsynStart 656 VsynStart 490
* HsynLenn 30 VsynLenn 2
*
* The linux framebuffer layer does not use the syncstart/synclen
* values but right/left/upper/lower margin values. The comments
* for the x_margin explain how to calculate those from given
* panel sync timings.
*/
static struct fb_videomode nl6448bc26 = {
.name = "NL6448BC26",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39683, /* in picoseconds! */
.hsync_len = 30,
.vsync_len = 2,
.left_margin = 114, /* HTOT - (HSYNSLEN + HSYNSTART) */
.right_margin = 16, /* HSYNSTART - XRES */
.upper_margin = 33, /* VTOT - (VSYNLEN + VSYNSTART) */
.lower_margin = 10, /* VSYNSTART - YRES */
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,
};
static struct sh7760fb_platdata sh7760fb_nl6448 = {
.def_mode = &nl6448bc26,
.ldmtr = LDMTR_TFT_COLOR_16, /* 16bit TFT panel */
.lddfr = LDDFR_8BPP, /* we want 8bit output */
.ldpmmr = 0x0070,
.ldpspr = 0x0500,
.ldaclnr = 0,
.ldickr = LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
LDICKR_CLKDIV(1),
.rotate = 0,
.novsync = 1,
.blank = NULL,
};
메모리·IRQ 자원과 platform device
104-130SH7760의 `0xFE300800`에는 256 x 4바이트 xRGB palette RAM이 있고, `0xFE300C00`에는 42바이트 control register가 있습니다. 예제의 메모리 자원은 전체 `0xFE300800`~`0xFE300CFF`를 `IORESOURCE_MEM`으로 등록합니다.
두 번째 자원은 IRQ 65 하나를 `IORESOURCE_IRQ`로 등록합니다. `struct platform_device sh7760_lcdc_dev`는 `.platform_data = &sh7760fb_nl6448`, 이름 `sh7760-lcdc`, ID -1, 자원 배열 `sh7760_lcdc_res`, 자원 수 `ARRAY_SIZE(sh7760_lcdc_res)`를 사용합니다.
/* SH7760:
* 0xFE300800: 256 * 4byte xRGB palette ram
* 0xFE300C00: 42 bytes ctrl registers
*/
static struct resource sh7760_lcdc_res[] = {
[0] = {
.start = 0xFE300800,
.end = 0xFE300CFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 65,
.end = 65,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sh7760_lcdc_dev = {
.dev = {
.platform_data = &sh7760fb_nl6448,
},
.name = "sh7760-lcdc",
.id = -1,
.resource = sh7760_lcdc_res,
.num_resources = ARRAY_SIZE(sh7760_lcdc_res),
};
요약·해설
sh7760fb.rst:1-130SH7760/SH7763 LCDC 드라이버는 연속 Area3 메모리와 선행 보드 초기화가 필수이며, 패널 timing을 `fb_videomode`, platform data, MMIO·IRQ 자원으로 기술합니다.
보드 초기화부터 platform device 등록까지의 의존 관계입니다.