요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
========================================
GPMC (General Purpose Memory Controller)
========================================
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
* Asynchronous SRAM like memories and application specific integrated
circuit devices.
* Asynchronous, synchronous, and page mode burst NOR flash devices
NAND flash
* Pseudo-SRAM devices
GPMC is found on Texas Instruments SoC's (OMAP based)
IP details: https://www.ti.com/lit/pdf/spruh73 section 7.1
GPMC generic timing calculation:
================================
GPMC has certain timings that has to be programmed for proper
functioning of the peripheral, while peripheral has another set of
timings. To have peripheral work with gpmc, peripheral timings has to
be translated to the form gpmc can understand. The way it has to be
translated depends on the connected peripheral. Also there is a
dependency for certain gpmc timings on gpmc clock frequency. Hence a
generic timing routine was developed to achieve above requirements.
Generic routine provides a generic method to calculate gpmc timings
from gpmc peripheral timings. struct gpmc_device_timings fields has to
be updated with timings from the datasheet of the peripheral that is
connected to gpmc. A few of the peripheral timings can be fed either
in time or in cycles, provision to handle this scenario has been
provided (refer struct gpmc_device_timings definition). It may so
happen that timing as specified by peripheral datasheet is not present
in timing structure, in this scenario, try to correlate peripheral
timing to the one available. If that doesn't work, try to add a new
field as required by peripheral, educate generic timing routine to
handle it, make sure that it does not break any of the existing.
Then there may be cases where peripheral datasheet doesn't mention
certain fields of struct gpmc_device_timings, zero those entries.
Generic timing routine has been verified to work properly on
multiple onenand's and tusb6010 peripherals.
A word of caution: generic timing routine has been developed based
on understanding of gpmc timings, peripheral timings, available
custom timing routines, a kind of reverse engineering without
most of the datasheets & hardware (to be exact none of those supported
in mainline having custom timing routine) and by simulation.
gpmc timing dependency on peripheral timings:
[<gpmc_timing>: <peripheral timing1>, <peripheral timing2> ...]
1. common
cs_on:
t_ceasu
adv_on:
t_avdasu, t_ceavd
2. sync common
sync_clk:
clk
page_burst_access:
t_bacc
clk_activation:
t_ces, t_avds
3. read async muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu, t_aavdh
access:
t_iaa, t_oe, t_ce, t_aa
rd_cycle:
t_rd_cycle, t_cez_r, t_oez
4. read async non-muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu
access:
t_iaa, t_oe, t_ce, t_aa
rd_cycle:
t_rd_cycle, t_cez_r, t_oez
5. read sync muxed
adv_rd_off:
t_avdp_r, t_avdh
oe_on:
t_oeasu, t_ach, cyc_aavdh_oe
access:
t_iaa, cyc_iaa, cyc_oe
rd_cycle:
t_cez_r, t_oez, t_ce_rdyz
6. read sync non-muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu
access:
t_iaa, cyc_iaa, cyc_oe
rd_cycle:
t_cez_r, t_oez, t_ce_rdyz
7. write async muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu, t_aavdh, cyc_aavhd_we
we_off:
t_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_wr_cycle
8. write async non-muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu
we_off:
t_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_wr_cycle
9. write sync muxed
adv_wr_off:
t_avdp_w, t_avdh
we_on, wr_data_mux_bus:
t_weasu, t_rdyo, t_aavdh, cyc_aavhd_we
we_off:
t_wpl, cyc_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_ce_rdyz
10. write sync non-muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu, t_rdyo
we_off:
t_wpl, cyc_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_ce_rdyz
Note:
Many of gpmc timings are dependent on other gpmc timings (a few
gpmc timings purely dependent on other gpmc timings, a reason that
some of the gpmc timings are missing above), and it will result in
indirect dependency of peripheral timings to gpmc timings other than
mentioned above, refer timing routine for more details. To know what
these peripheral timings correspond to, please see explanations in
struct gpmc_device_timings definition. And for gpmc timings refer
IP details (link above).
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
GPMC 개요
1-19GPMC, 즉 General Purpose Memory Controller는 여러 external memory device를 연결하는 통합 memory controller입니다.
대상에는 asynchronous SRAM 계열 memory와 application-specific IC, asynchronous·synchronous·page-mode burst NOR flash, NAND flash, pseudo-SRAM이 있습니다.
GPMC는 OMAP 기반 Texas Instruments SoC에 있으며 IP 상세는 TI 기술 문서 `spruh73`의 7.1절에서 확인할 수 있습니다.
.. SPDX-License-Identifier: GPL-2.0
========================================
GPMC (General Purpose Memory Controller)
========================================
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
* Asynchronous SRAM like memories and application specific integrated
circuit devices.
* Asynchronous, synchronous, and page mode burst NOR flash devices
NAND flash
* Pseudo-SRAM devices
GPMC is found on Texas Instruments SoC's (OMAP based)
IP details: https://www.ti.com/lit/pdf/spruh73 section 7.1
Generic timing 계산
20-53GPMC가 peripheral과 올바르게 동작하려면 controller timing을 program해야 하지만 peripheral datasheet는 별도 timing 집합을 제공합니다. 연결 장치에 따라 peripheral timing을 GPMC가 이해하는 형식으로 변환해야 하며 일부 GPMC timing은 GPMC clock frequency에도 의존합니다.
Generic routine은 `gpmc_device_timings`에 넣은 peripheral datasheet timing으로 GPMC timing을 계산합니다. 일부 값은 시간 또는 cycle 단위로 전달할 수 있습니다.
Datasheet timing이 구조체에 직접 없으면 기존 field와 대응 관계를 찾아야 합니다. 대응할 수 없다면 새 field와 계산 지원을 추가하되 기존 장치를 깨뜨리지 않아야 합니다. Datasheet에 없는 field는 0으로 설정합니다.
Generic routine은 여러 OneNAND와 TUSB6010 peripheral에서 검증되었습니다.
이 routine은 제한된 datasheet와 hardware 상황에서 기존 custom routine의 reverse engineering과 simulation을 바탕으로 개발되었으므로 주의해서 사용해야 합니다.
Peripheral datasheet 값을 controller clock과 mode에 맞는 GPMC register timing으로 변환합니다.
GPMC generic timing calculation:
================================
GPMC has certain timings that has to be programmed for proper
functioning of the peripheral, while peripheral has another set of
timings. To have peripheral work with gpmc, peripheral timings has to
be translated to the form gpmc can understand. The way it has to be
translated depends on the connected peripheral. Also there is a
dependency for certain gpmc timings on gpmc clock frequency. Hence a
generic timing routine was developed to achieve above requirements.
Generic routine provides a generic method to calculate gpmc timings
from gpmc peripheral timings. struct gpmc_device_timings fields has to
be updated with timings from the datasheet of the peripheral that is
connected to gpmc. A few of the peripheral timings can be fed either
in time or in cycles, provision to handle this scenario has been
provided (refer struct gpmc_device_timings definition). It may so
happen that timing as specified by peripheral datasheet is not present
in timing structure, in this scenario, try to correlate peripheral
timing to the one available. If that doesn't work, try to add a new
field as required by peripheral, educate generic timing routine to
handle it, make sure that it does not break any of the existing.
Then there may be cases where peripheral datasheet doesn't mention
certain fields of struct gpmc_device_timings, zero those entries.
Generic timing routine has been verified to work properly on
multiple onenand's and tusb6010 peripherals.
A word of caution: generic timing routine has been developed based
on understanding of gpmc timings, peripheral timings, available
custom timing routines, a kind of reverse engineering without
most of the datasheets & hardware (to be exact none of those supported
in mainline having custom timing routine) and by simulation.
공통·synchronous timing dependency
54-73공통 timing에서 `cs_on`은 `t_ceasu`, `adv_on`은 `t_avdasu`와 `t_ceavd`에 의존합니다.
Synchronous 공통 timing에서 `sync_clk`는 `clk`, `page_burst_access`는 `t_bacc`, `clk_activation`은 `t_ces`와 `t_avds`에 의존합니다.
gpmc timing dependency on peripheral timings:
[<gpmc_timing>: <peripheral timing1>, <peripheral timing2> ...]
1. common
cs_on:
t_ceasu
adv_on:
t_avdasu, t_ceavd
2. sync common
sync_clk:
clk
page_burst_access:
t_bacc
clk_activation:
t_ces, t_avds
Read mode timing dependency
74-117Asynchronous muxed read에서 `adv_rd_off`는 `t_avdp_r`, `oe_on`은 `t_oeasu`·`t_aavdh`, `access`는 `t_iaa`·`t_oe`·`t_ce`·`t_aa`, `rd_cycle`은 `t_rd_cycle`·`t_cez_r`·`t_oez`에 의존합니다.
Asynchronous non-muxed read에서는 `oe_on`에서 `t_aavdh`가 빠지고 나머지 mapping은 동일합니다.
Synchronous muxed read에서 `adv_rd_off`는 `t_avdp_r`·`t_avdh`, `oe_on`은 `t_oeasu`·`t_ach`·`cyc_aavdh_oe`, `access`는 `t_iaa`·`cyc_iaa`·`cyc_oe`, `rd_cycle`은 `t_cez_r`·`t_oez`·`t_ce_rdyz`에 의존합니다.
Synchronous non-muxed read에서는 `adv_rd_off`가 `t_avdp_r`, `oe_on`이 `t_oeasu`이고 access와 cycle mapping은 synchronous muxed mode와 같습니다.
3. read async muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu, t_aavdh
access:
t_iaa, t_oe, t_ce, t_aa
rd_cycle:
t_rd_cycle, t_cez_r, t_oez
4. read async non-muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu
access:
t_iaa, t_oe, t_ce, t_aa
rd_cycle:
t_rd_cycle, t_cez_r, t_oez
5. read sync muxed
adv_rd_off:
t_avdp_r, t_avdh
oe_on:
t_oeasu, t_ach, cyc_aavdh_oe
access:
t_iaa, cyc_iaa, cyc_oe
rd_cycle:
t_cez_r, t_oez, t_ce_rdyz
6. read sync non-muxed
adv_rd_off:
t_avdp_r
oe_on:
t_oeasu
access:
t_iaa, cyc_iaa, cyc_oe
rd_cycle:
t_cez_r, t_oez, t_ce_rdyz
Write mode timing dependency
118-169Asynchronous muxed write에서 `adv_wr_off`는 `t_avdp_w`, `we_on`·`wr_data_mux_bus`는 `t_weasu`·`t_aavdh`·`cyc_aavhd_we`, `we_off`는 `t_wpl`, `cs_wr_off`는 `t_wph`, `wr_cycle`은 `t_cez_w`·`t_wr_cycle`에 의존합니다.
Asynchronous non-muxed write에서는 `we_on`·`wr_data_mux_bus`가 `t_weasu`에만 의존하고 나머지는 같은 mapping을 사용합니다.
Synchronous muxed write에서 `adv_wr_off`는 `t_avdp_w`·`t_avdh`, `we_on`·`wr_data_mux_bus`는 `t_weasu`·`t_rdyo`·`t_aavdh`·`cyc_aavhd_we`, `we_off`는 `t_wpl`·`cyc_wpl`, `cs_wr_off`는 `t_wph`, `wr_cycle`은 `t_cez_w`·`t_ce_rdyz`에 의존합니다.
Synchronous non-muxed write에서는 `adv_wr_off`가 `t_avdp_w`, `we_on`·`wr_data_mux_bus`가 `t_weasu`·`t_rdyo`이고 나머지는 synchronous muxed mode와 같습니다.
7. write async muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu, t_aavdh, cyc_aavhd_we
we_off:
t_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_wr_cycle
8. write async non-muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu
we_off:
t_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_wr_cycle
9. write sync muxed
adv_wr_off:
t_avdp_w, t_avdh
we_on, wr_data_mux_bus:
t_weasu, t_rdyo, t_aavdh, cyc_aavhd_we
we_off:
t_wpl, cyc_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_ce_rdyz
10. write sync non-muxed
adv_wr_off:
t_avdp_w
we_on, wr_data_mux_bus:
t_weasu, t_rdyo
we_off:
t_wpl, cyc_wpl
cs_wr_off:
t_wph
wr_cycle:
t_cez_w, t_ce_rdyz
간접 timing dependency
170-179많은 GPMC timing은 다른 GPMC timing에 의존합니다. 일부는 전적으로 다른 controller timing에서 계산되므로 앞의 목록에 나타나지 않습니다.
따라서 peripheral timing은 위에 직접 적힌 것 외의 GPMC timing에도 간접적으로 영향을 줄 수 있습니다. 상세 dependency는 timing routine을 확인해야 합니다.
Peripheral timing의 정의는 `gpmc_device_timings`, GPMC timing은 앞서 연결된 IP 문서를 참고합니다.
Peripheral timing이 중간 GPMC timing을 거쳐 다른 controller timing에 영향을 줄 수 있습니다.
Note:
Many of gpmc timings are dependent on other gpmc timings (a few
gpmc timings purely dependent on other gpmc timings, a reason that
some of the gpmc timings are missing above), and it will result in
indirect dependency of peripheral timings to gpmc timings other than
mentioned above, refer timing routine for more details. To know what
these peripheral timings correspond to, please see explanations in
struct gpmc_device_timings definition. And for gpmc timings refer
IP details (link above).
요약과 해설
ti-gpmc.rst:1-179Generic timing routine은 peripheral datasheet의 시간·cycle 조건을 GPMC clock과 mux·sync mode에 맞는 controller timing으로 변환합니다.