요즘같은 SOC 환경에서 개발하다 보면 chip 내부에 각 hw block 마다 clock 을 enable / disable 해서 컨트롤 하게 됩니다. 이는 power save 측면에서도 중요한 사항이지요.
이러한 clock control 에 대한 general methord 에 대해 이야기 하려고 합니다.
omap 과 s3c 시리즈에서 하용되는 코드지만 많은 칩셋들이 이와같이 동작하리라 봅니다.
arch \ arm \ plat-chip명칭 \ clock.c
를 보면 아래와 같이 각 clock 의 device 들이 등록되어 있습니다.
static struct clk init_clocks[] = {
...
}, {
.name = "spi",
.id = 0,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI0,
}, {
.name = "spi",
.id = 1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI1,
}, {
.name = "spi",
.id = 2,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI2,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_PWM,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_TSADC,
}, {
.name = "keypad",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_KEYIF,
},
...
}
...
}, {
.name = "spi",
.id = 0,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI0,
}, {
.name = "spi",
.id = 1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI1,
}, {
.name = "spi",
.id = 2,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_SPI2,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_PWM,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_TSADC,
}, {
.name = "keypad",
.id = -1,
.parent = &clk_p66,
.enable = s5pc11x_clk_ip3_ctrl,
.ctrlbit = S5P_CLKGATE_IP3_KEYIF,
},
...
}
제가 이번 디바이스에서 쓰려고 하는 clock 은 pwm 입니다.
선언한 device 의 name 인 "timers" 로 driver 를 불러올 수 있습니다.
void s3c_pwm_timer_clk(void)
{
unsigned long pclk=0;
DbgOut((KERN_DEBUG "[VIB] %s()\n", __FUNCTION__));
clk = clk_get(NULL, "timers");
if (IS_ERR(clk))
panic("failed to get clock for system timer");
pclk = clk_get_rate(clk);
}
void GPtimer_disable(void)
{
DbgOut((KERN_DEBUG "[VIB] %s()\n", __FUNCTION__));
clk_disable(clk);
}
void GPtimer_enable()
{
DbgOut((KERN_DEBUG "[VIB] %s()\n", __FUNCTION__));
clk_enable(clk);
}
이름은 GPtime 이지만 실질적으로 pwm hw block 의 source clock 을 켜고 끌 수 있습니다.
참 쉽죠잉~
알고나면 쉽지만 모를때는 무한 삽질하게 되는것이 linux 인듯 합니다.
자.. 오늘도 열공 ^^
'Programming > Linux_Kernel' 카테고리의 다른 글
linux proc 정보 (0) | 2010.02.25 |
---|---|
linux 병목현상 분석 : latencytop (0) | 2010.02.23 |
slab cache - 생성과 파괴를 반복하는 커다란 자료구조 관리 (0) | 2010.02.17 |
misc 에 sysfs 등록하기 (0) | 2010.02.08 |
linux 레지스터 맵핑주소 찾기 (0) | 2010.02.08 |