顯示具有 s3c2440 標籤的文章。 顯示所有文章
顯示具有 s3c2440 標籤的文章。 顯示所有文章

2009年12月16日 星期三

SD driver with DMA support

有在研究 S3C24XX 平台的開發者應該會發現,SD 控制器驅動程式目前只支援 PIO mode,若嘗試將 DMA mode 的支援開啟,在偵測 SD 卡時就會發生問題。經過原始碼追蹤後我們可以發現到一些現象,且待我細細道來。

S3C24XX 平台的 DMA core 實作了要求佇列 (request queue) 的機制,使得它能夠接收多個 DMA 傳輸要求,並設定相關的暫存器來進行傳輸。當設定完成後,我們就可以設定 SD 控制器來觸發 DMA 控制器進行實際的資料傳輸。當要求佇列中有新的傳輸要求存在時,DMA core 會檢查 DMA 控制器是否已經在執行目前的要求;若已在執行,DMA core 就會取出新的要求,並將來源位址、目的位址以及資料長度等參數寫入暫存器中 (對暫存器寫入並不會對進行中的傳輸產生影響)。若否,DMA core 會繼續等待直到逾時為止。換言之,除非 DMA 控制器起始傳輸,否則 DMA core 是不會處理新的傳輸要求的。

MMC core 在讀取資料的過程中,預設會使用 scatter-gather DMA 來提高傳輸效率,或避免向核心要求一大塊連續的記憶體空間;然而 S3C24XX DMA 控制器並不支援此種傳輸方式,因此在執行時我們就會發現到,由於佇列中還有傳輸要求尚未設定,DMA core 不斷地在檢查 DMA 控制器是否正在執行;但是在佇列中的所有傳輸要求都被設定完成之前,SD 控制器是不會觸發 DMA 控制器來起始傳輸的 (雞生蛋,蛋生雞?),於是我們就會看到 DMA core 一直在 busy waiting,直到 time out 為止。

因此要解決這樣的問題,在向 MMC core 註冊 host controller 時,要設定該控制器同時間只能接受一個 DMA 傳輸要求 (請見 struct mmc_host 中的 max_hw_segs 及 max_phys_segs 欄位)。同時也可開啟 bounce buffer 支援以提高傳輸效率。

2009年10月28日 星期三

Samsung touchscreen driver issue

三星的主流核心支援其實已存在相當久,幾乎可說是所有 ARM-based SoC 中支援最完整的。但經常關心 ARM Linux kernel 發展的網友也許會發現到,怎麼核心中每項周邊都有驅動程式支援,卻獨獨缺了觸控面板?

其實相關的 patch 早已在各個專案中使用 (如 OpenMoko),但由於都是直接操作暫存器,而非架構在 Ben Dooks 的 adc driver 之上(詳見之前的文章),是故一直沒有被整合進去。今年四月初 Nelson Castillo 將原來在 OpenMoko 使用的驅動程式移植至主流核心,並使用 adc driver 來做取樣的工作。雖然已有作為先期準備的 patch 被整合,但直到目前為止完整的驅動程式仍未進行合併。

最近關於這個議題又有了新的爭論。由於 Nelson 的版本引進了多層次的濾波器(filter)來去除不合法的取樣點,Russell King 認為這違背了 policy-mechanism 分離的原則;所有的取樣點應該原封不動地往上傳遞至 user-space(tslib)來做處理,在驅動程式中使用 filter 是缺乏彈性的作法(附帶一提,Russell 是 tslib 的作者)。但 Nelson 認為,在驅動程式中,filter 可以根據需要,透過回傳值來要求 adc driver 多抓一些取樣點來作判斷;而這是 user-space 所無法達成的優點。且這樣的設計方式可以解決在電阻式面板所遇到的問題(在觸控筆按下和釋放的瞬間,會有大量的雜訊出現)。

就我個人測試過的經驗,Nelson 的 patch 確實比單純只使用 tslib,觸控板的表現要好得多,筆觸變得比較順暢,且抖動的情況減少很多。雖然在整合進 board-dependent 的程式碼時相對比較麻煩,不過其效果似乎是值得這麼做的。

2009年5月13日 星期三

S3C24xx ADC driver (2)

第一篇文章中我們提到,adc driver 簡化了一部分硬體操作的細節,並提供 API 讓驅動程式使用。但就 touchscreen 驅動程式開發者的立場來看,它仍然有一些問題(以下純屬個人意見,僅供參考):
  • 雖然它給予驅動程式開發者在擷取數據上的方便性,但並未處理與觸控板相關的硬體操作,故開發者仍必須自行設定相關的暫存器來處理按下及釋放的事件;由於 ADC 硬體本身就額外支援觸控板的功能,adc driver 做為硬體與 touchscreen driver 間的中介層,應儘量隱藏硬體的細節,並提供完整的介面供上層驅動程式使用,而如今開發者除了須自行設定暫存器外,還必須先查看 adc driver 的原始碼,了解它如何設定暫存器,以避免自己的程式碼去干擾 adc driver 的運作,似乎失去了資訊隱藏的意義。
  • 這點比較見人見智;一般來說,驅動程式在呼叫 ioremap() 之前,會先呼叫 request_mem_region() 來防止其他驅動程式存取特定的暫存器群。但為了讓 touchscreen driver 也能夠存取暫存器,adc driver 允許 touchscreen driver 映射該區塊,於是變成兩個驅動程式存取同一組暫存器群的局面。我是不知道其他人怎麼想,但我就是覺得很怪,其中一部分程式碼若不小心更新了不該更新的暫存器,那是有可能會影響到另一個驅動程式的運作,造成潛在的錯誤。
基於上述兩項理由,我曾徵詢是否可將觸控板的功能也納入 adc driver 之中,也弄了一個 patch,不過 Ben 認為應該要維持程式碼的簡潔,因此否決了這個提議。

也許以後會有所改變吧,不過,誰知道呢 :)

2009年4月3日 星期五

S3C24xx ADC driver

上個月花了相當多的時間在研究 S3C24xx 的觸控面板控制器和驅動程式,在這邊稍微分享一下心得,並介紹目前在 mainstream kernel 所實做的 ADC driver core。

S3C24xx 的 ADC 控制器共有 8 個 channel,其中有四個 channel 可設定來接收觸控螢幕的訊號,並提供多種轉換模式,例如手動轉換 x 及 y 座標,或是讓控制器自動轉換等等。同時控制器也可偵測觸控筆「按下」或「釋放」的動作。但是需注意的是,同一時間只能有一種模式可以運作;換言之,驅動程式必須適時地在以下三種模式間切換:
  • 偵測「按下」的動作
  • 偵測「釋放」的動作
  • 取樣並轉換 x 及 y 座標
設定不同的模式皆需要對暫存器 (ADCTSC) 寫入不同的值。

除了被用做接收觸控訊號的四個 channel 外,剩下的另外四個則可連接其他的感測器。過去分散於各個專案中的觸控驅動程式 (截至目前尚未整合進入 mainstream),都是直接操作控制器,因而多出的四個 channel 即便接上了裝置,該驅動程式也無法與 touchscreen driver 共存 (不同的 driver 存取同一組暫存器會發生 race condition 的問題)。因此為了讓這些不同裝置的驅動程式能夠共用該控制器,Ben Dooks 在 2.6.28 引入了 ADC driver core (以下簡稱 adc driver),定義了一組介面,讓上層驅動程式能夠透過該介面來使用控制器。

若要使用 adc driver,驅動程式需要定義自己的回呼函式 (callback function),並向它註冊,註冊函式會回傳一個型態為 s3c_adc_client 的指標,其後的函式呼叫則以該指標做為第一個引數。adc driver 內部維護了一個要求佇列來紀錄來自外部的服務需求,並給予觸控有關的需求最高的優先權,以便可即時回應使用者的操作。在運作過程中,adc driver 會不斷地呼叫先前所註冊的 callback 以通知驅動程式處理取樣的數據,次數則可在要求服務時以參數設定。

對觸控驅動程式的開發者來說,adc driver 簡化了一部分複雜的細節,讓開發者透過函式介面來要求服務,而不必操作底層的暫存器。但我必須指出,它只是簡化了「一部分」,並非全部;至於為何,我們留待下一篇文章來探討。

2008年6月29日 星期日

網路支援完成

最近這二天適逢周末,我趁著有空閒時,開始來研究 git kernel 及原廠自行修改的 DM9000 網路晶片驅動程式原始碼。不過兩相對照之下,初始化過程其實差不多,雖然在 dm9000_rx() 函式中程式有些不同,不過經過測試後發現其實沒什麼影響。後來我根據初始化時所做的條件判斷及開發板的線路圖,在開發板初始化程式中再加入了以下的定義:

static struct dm9000_plat_data at2440evb_dm9k_pdata = {
    .flags = (DM9000_PLATF_8BITONLY | DM9000_PLATF_NO_EEPROM),
};

意思是指示驅動程式晶片的資料埠寬度為 8 bits,且晶片並未連接 eeprom。
不過測試時卻無法驅動。我照著線路圖和晶片手冊設定的應該沒錯,可就是不會動,真是百思不得其解。後來無意間設定成 DM9000_PLATF_16BITONLY,竟然就可以動了…可是這樣一來就和線路圖產生矛盾了…難不成廠商給我的是錯的???有必要再釐清一下。

花了一個下午的時間,網路算是可以正常工作了,稍後整理一下就可以送 patch 了。

2008年6月17日 星期二

開機成功

經過幾天的 code tracing,大致上已經了解 S3C24xx 架構的原始碼是如何安排的,接下來我在 ARM Linux 的 machine registry 去註冊了新的 machine type,接著開始移植的工作。我先以 arch/arm/s3c2440/ 目錄下的 mach-anubis.c 為樣板,刪去了不需要的程式碼,並加入了一些板子獨有的硬體設定,接著修改 Kconfig 以及 Makefile,最後重新編譯核心,第一階段完成。

接下來將核心的 rootfs 掛載為 initramfs,可以順利開機,其他基本的驅動程式,如 RTC,UART,NAND 等也順利啟動,唯一有問題的就是網路晶片。核心原始碼中已附有 DM9000 的驅動程式,但不知為何,無法正確驅動,我猜測可能是始初化過程的問題。最近這幾天要再拿隨貨附的原始程式來對照一下。

以上。

2008年6月12日 星期四

目前工作

目前正在進行的項目是將最新版本的 Linux kernel (2.6.26-rc5)移植到這塊開發板上。雖然購買這塊板子時已隨貨附上修改過的 Linux 2.6.18.2 原始碼,但原作者似乎並未將這些修正合併回主流核心版本中。是故我的計畫是將這些修改過的程式做個整理,以符合核心的 coding style,然後註冊新的 machine type,將整理完的程式碼送上 mailing list。

當然過程中,仍少不了要追蹤硬體初始化的部分,來和晶片使用手冊的說明相對照。所幸拜 Ben Dooks 的努力,S3C24xx 系列的程式碼發展地相當完整,要加入新開發板的支援比較方便,只要將現有的程式碼拿來直接套用即可,剩下的工作就是針對開發板上特殊的周邊做些修改了。

2008年5月26日 星期一

S3C2440 開發板初體驗

自從上禮拜收到貨之後,由於本人那幾天比較忙,懶得動,是故清點完包裝內的物品後,便暫時擱在一旁。今天終於有空來玩一玩。

代理商出貨時就有先幫我燒好 Linux,是故接上 LCD 後開機就可以順利顯示圖形界面,可以確定 LCD driver 沒問題。再來開到以 COM port 連接的終端機檢視其中的 /proc 目錄,確認 CPU 的型別、記憶體大小、已驅動的裝置,再來做幾個測試,小結如下:
  • USB Host:可連接 mass storage device
  • MTD:可正確讀出/寫入
  • OSS:可正確播放音效。不過聲音有點破破的。
  • UART:沒問題
  • Framebuffer:沒問題
目前做到這裡,接下來再來寫幾個簡單的 kernel module 來測試其他硬體。

此外,這塊板子出廠附的 bootloader 並非是 U-Boot,而是廠商自己做的 bootloader,主要功能是將 NAND Flash 自動分區並燒錄核心及檔案系統,雖然支援以 USB 下載檔案是很方便沒錯,但除了燒錄外,其他功能付之闕如。因此我想玩玩過後,還是會重新再燒個 U-Boot 吧。

2008年5月23日 星期五

新開發板入手

今天終於收到昨天新買的 s3c2440 開發板。眾所周知,三星所推出以 ARM 為基礎的 SoC 一直以「俗擱大碗」著稱;不僅價格便宜,許多該有的周邊 IO 也都不缺,不僅在學校實習課上常用到,也是像我們這些阮囊羞澀的窮人不錯的選擇。

唯一我比較在意的是,這塊板子是大陸做的;一般人印象中總是對大陸產品有品質不佳的印象,尤其代理商又賣我這麼便宜,實在很難不讓人起疑。不過在網路上找來找去,s3c2440 的開發板似乎沒有很多選擇,加上並非都有台灣的代理商在賣,我又懶得直接跟原廠購買,就姑且信之吧。好在廠商附的文件倒是不少,該有的燒錄工具也都送給你,按步就班地做,希望不會出什麼大問題。

總之,這算是我生平第一塊自費的 ARM 開發板,就來好好研究研究唄。

後記:
後來在 http://www.arm.linux.org.uk/developer/machines/ 上看到不少 2440 為基礎的開發板,不過似乎在原始碼中沒看到這麼多啊?還是只是註冊假的?