Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
c818f97b
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c818f97b
编写于
5月 09, 2012
作者:
S
Sascha Hauer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ARM i.MX: remove now unused clock files
Signed-off-by:
N
Sascha Hauer
<
s.hauer@pengutronix.de
>
上级
2acd1b6f
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
0 addition
and
7958 deletion
+0
-7958
arch/arm/mach-imx/clock-imx1.c
arch/arm/mach-imx/clock-imx1.c
+0
-636
arch/arm/mach-imx/clock-imx21.c
arch/arm/mach-imx/clock-imx21.c
+0
-1239
arch/arm/mach-imx/clock-imx25.c
arch/arm/mach-imx/clock-imx25.c
+0
-346
arch/arm/mach-imx/clock-imx27.c
arch/arm/mach-imx/clock-imx27.c
+0
-785
arch/arm/mach-imx/clock-imx31.c
arch/arm/mach-imx/clock-imx31.c
+0
-630
arch/arm/mach-imx/clock-imx35.c
arch/arm/mach-imx/clock-imx35.c
+0
-536
arch/arm/mach-imx/clock-imx6q.c
arch/arm/mach-imx/clock-imx6q.c
+0
-2111
arch/arm/mach-imx/clock-mx51-mx53.c
arch/arm/mach-imx/clock-mx51-mx53.c
+0
-1675
未找到文件。
arch/arm/mach-imx/clock-imx1.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
/*
* Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/math64.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
/* CCM register addresses */
#define CCM_CSCR IO_ADDR_CCM(0x0)
#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
#define CCM_PCDR IO_ADDR_CCM(0x20)
#define CCM_CSCR_CLKO_OFFSET 29
#define CCM_CSCR_CLKO_MASK (0x7 << 29)
#define CCM_CSCR_USB_OFFSET 26
#define CCM_CSCR_USB_MASK (0x7 << 26)
#define CCM_CSCR_OSC_EN_SHIFT 17
#define CCM_CSCR_SYSTEM_SEL (1 << 16)
#define CCM_CSCR_BCLK_OFFSET 10
#define CCM_CSCR_BCLK_MASK (0xf << 10)
#define CCM_CSCR_PRESC (1 << 15)
#define CCM_PCDR_PCLK3_OFFSET 16
#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
#define CCM_PCDR_PCLK2_OFFSET 4
#define CCM_PCDR_PCLK2_MASK (0xf << 4)
#define CCM_PCDR_PCLK1_OFFSET 0
#define CCM_PCDR_PCLK1_MASK 0xf
#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
/* SCM register addresses */
#define SCM_GCCR IO_ADDR_SCM(0xc)
#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
static
int
_clk_enable
(
struct
clk
*
clk
)
{
unsigned
int
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
|=
1
<<
clk
->
enable_shift
;
__raw_writel
(
reg
,
clk
->
enable_reg
);
return
0
;
}
static
void
_clk_disable
(
struct
clk
*
clk
)
{
unsigned
int
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
&=
~
(
1
<<
clk
->
enable_shift
);
__raw_writel
(
reg
,
clk
->
enable_reg
);
}
static
int
_clk_can_use_parent
(
const
struct
clk
*
clk_arr
[],
unsigned
int
size
,
struct
clk
*
parent
)
{
int
i
;
for
(
i
=
0
;
i
<
size
;
i
++
)
if
(
parent
==
clk_arr
[
i
])
return
i
;
return
-
EINVAL
;
}
static
unsigned
long
_clk_simple_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
,
unsigned
int
limit
)
{
int
div
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
parent_rate
%
rate
)
div
++
;
if
(
div
>
limit
)
div
=
limit
;
return
parent_rate
/
div
;
}
static
unsigned
long
_clk_parent_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk
->
parent
->
round_rate
(
clk
->
parent
,
rate
);
}
static
int
_clk_parent_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk
->
parent
->
set_rate
(
clk
->
parent
,
rate
);
}
static
unsigned
long
clk16m_get_rate
(
struct
clk
*
clk
)
{
return
16000000
;
}
static
struct
clk
clk16m
=
{
.
get_rate
=
clk16m_get_rate
,
.
enable
=
_clk_enable
,
.
enable_reg
=
CCM_CSCR
,
.
enable_shift
=
CCM_CSCR_OSC_EN_SHIFT
,
.
disable
=
_clk_disable
,
};
/* in Hz */
static
unsigned
long
clk32_rate
;
static
unsigned
long
clk32_get_rate
(
struct
clk
*
clk
)
{
return
clk32_rate
;
}
static
struct
clk
clk32
=
{
.
get_rate
=
clk32_get_rate
,
};
static
unsigned
long
clk32_premult_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
*
512
;
}
static
struct
clk
clk32_premult
=
{
.
parent
=
&
clk32
,
.
get_rate
=
clk32_premult_get_rate
,
};
static
const
struct
clk
*
prem_clk_clocks
[]
=
{
&
clk32_premult
,
&
clk16m
,
};
static
int
prem_clk_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
int
i
;
unsigned
int
reg
=
__raw_readl
(
CCM_CSCR
);
i
=
_clk_can_use_parent
(
prem_clk_clocks
,
ARRAY_SIZE
(
prem_clk_clocks
),
parent
);
switch
(
i
)
{
case
0
:
reg
&=
~
CCM_CSCR_SYSTEM_SEL
;
break
;
case
1
:
reg
|=
CCM_CSCR_SYSTEM_SEL
;
break
;
default:
return
i
;
}
__raw_writel
(
reg
,
CCM_CSCR
);
return
0
;
}
static
struct
clk
prem_clk
=
{
.
set_parent
=
prem_clk_set_parent
,
};
static
unsigned
long
system_clk_get_rate
(
struct
clk
*
clk
)
{
return
mxc_decode_pll
(
__raw_readl
(
CCM_SPCTL0
),
clk_get_rate
(
clk
->
parent
));
}
static
struct
clk
system_clk
=
{
.
parent
=
&
prem_clk
,
.
get_rate
=
system_clk_get_rate
,
};
static
unsigned
long
mcu_clk_get_rate
(
struct
clk
*
clk
)
{
return
mxc_decode_pll
(
__raw_readl
(
CCM_MPCTL0
),
clk_get_rate
(
clk
->
parent
));
}
static
struct
clk
mcu_clk
=
{
.
parent
=
&
clk32_premult
,
.
get_rate
=
mcu_clk_get_rate
,
};
static
unsigned
long
fclk_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
fclk
=
clk_get_rate
(
clk
->
parent
);
if
(
__raw_readl
(
CCM_CSCR
)
&
CCM_CSCR_PRESC
)
fclk
/=
2
;
return
fclk
;
}
static
struct
clk
fclk
=
{
.
parent
=
&
mcu_clk
,
.
get_rate
=
fclk_get_rate
,
};
/*
* get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
*/
static
unsigned
long
hclk_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
(((
__raw_readl
(
CCM_CSCR
)
&
CCM_CSCR_BCLK_MASK
)
>>
CCM_CSCR_BCLK_OFFSET
)
+
1
);
}
static
unsigned
long
hclk_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
_clk_simple_round_rate
(
clk
,
rate
,
16
);
}
static
int
hclk_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
int
div
;
unsigned
int
reg
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
div
>
16
||
div
<
1
||
((
parent_rate
/
div
)
!=
rate
))
return
-
EINVAL
;
div
--
;
reg
=
__raw_readl
(
CCM_CSCR
);
reg
&=
~
CCM_CSCR_BCLK_MASK
;
reg
|=
div
<<
CCM_CSCR_BCLK_OFFSET
;
__raw_writel
(
reg
,
CCM_CSCR
);
return
0
;
}
static
struct
clk
hclk
=
{
.
parent
=
&
system_clk
,
.
get_rate
=
hclk_get_rate
,
.
round_rate
=
hclk_round_rate
,
.
set_rate
=
hclk_set_rate
,
};
static
unsigned
long
clk48m_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
(((
__raw_readl
(
CCM_CSCR
)
&
CCM_CSCR_USB_MASK
)
>>
CCM_CSCR_USB_OFFSET
)
+
1
);
}
static
unsigned
long
clk48m_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
_clk_simple_round_rate
(
clk
,
rate
,
8
);
}
static
int
clk48m_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
int
div
;
unsigned
int
reg
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
div
>
8
||
div
<
1
||
((
parent_rate
/
div
)
!=
rate
))
return
-
EINVAL
;
div
--
;
reg
=
__raw_readl
(
CCM_CSCR
);
reg
&=
~
CCM_CSCR_USB_MASK
;
reg
|=
div
<<
CCM_CSCR_USB_OFFSET
;
__raw_writel
(
reg
,
CCM_CSCR
);
return
0
;
}
static
struct
clk
clk48m
=
{
.
parent
=
&
system_clk
,
.
get_rate
=
clk48m_get_rate
,
.
round_rate
=
clk48m_round_rate
,
.
set_rate
=
clk48m_set_rate
,
};
/*
* get peripheral clock 1 ( UART[12], Timer[12], PWM )
*/
static
unsigned
long
perclk1_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
(((
__raw_readl
(
CCM_PCDR
)
&
CCM_PCDR_PCLK1_MASK
)
>>
CCM_PCDR_PCLK1_OFFSET
)
+
1
);
}
static
unsigned
long
perclk1_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
_clk_simple_round_rate
(
clk
,
rate
,
16
);
}
static
int
perclk1_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
int
div
;
unsigned
int
reg
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
div
>
16
||
div
<
1
||
((
parent_rate
/
div
)
!=
rate
))
return
-
EINVAL
;
div
--
;
reg
=
__raw_readl
(
CCM_PCDR
);
reg
&=
~
CCM_PCDR_PCLK1_MASK
;
reg
|=
div
<<
CCM_PCDR_PCLK1_OFFSET
;
__raw_writel
(
reg
,
CCM_PCDR
);
return
0
;
}
/*
* get peripheral clock 2 ( LCD, SD, SPI[12] )
*/
static
unsigned
long
perclk2_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
(((
__raw_readl
(
CCM_PCDR
)
&
CCM_PCDR_PCLK2_MASK
)
>>
CCM_PCDR_PCLK2_OFFSET
)
+
1
);
}
static
unsigned
long
perclk2_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
_clk_simple_round_rate
(
clk
,
rate
,
16
);
}
static
int
perclk2_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
int
div
;
unsigned
int
reg
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
div
>
16
||
div
<
1
||
((
parent_rate
/
div
)
!=
rate
))
return
-
EINVAL
;
div
--
;
reg
=
__raw_readl
(
CCM_PCDR
);
reg
&=
~
CCM_PCDR_PCLK2_MASK
;
reg
|=
div
<<
CCM_PCDR_PCLK2_OFFSET
;
__raw_writel
(
reg
,
CCM_PCDR
);
return
0
;
}
/*
* get peripheral clock 3 ( SSI )
*/
static
unsigned
long
perclk3_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
(((
__raw_readl
(
CCM_PCDR
)
&
CCM_PCDR_PCLK3_MASK
)
>>
CCM_PCDR_PCLK3_OFFSET
)
+
1
);
}
static
unsigned
long
perclk3_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
_clk_simple_round_rate
(
clk
,
rate
,
128
);
}
static
int
perclk3_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
int
div
;
unsigned
int
reg
;
unsigned
long
parent_rate
;
parent_rate
=
clk_get_rate
(
clk
->
parent
);
div
=
parent_rate
/
rate
;
if
(
div
>
128
||
div
<
1
||
((
parent_rate
/
div
)
!=
rate
))
return
-
EINVAL
;
div
--
;
reg
=
__raw_readl
(
CCM_PCDR
);
reg
&=
~
CCM_PCDR_PCLK3_MASK
;
reg
|=
div
<<
CCM_PCDR_PCLK3_OFFSET
;
__raw_writel
(
reg
,
CCM_PCDR
);
return
0
;
}
static
struct
clk
perclk
[]
=
{
{
.
id
=
0
,
.
parent
=
&
system_clk
,
.
get_rate
=
perclk1_get_rate
,
.
round_rate
=
perclk1_round_rate
,
.
set_rate
=
perclk1_set_rate
,
},
{
.
id
=
1
,
.
parent
=
&
system_clk
,
.
get_rate
=
perclk2_get_rate
,
.
round_rate
=
perclk2_round_rate
,
.
set_rate
=
perclk2_set_rate
,
},
{
.
id
=
2
,
.
parent
=
&
system_clk
,
.
get_rate
=
perclk3_get_rate
,
.
round_rate
=
perclk3_round_rate
,
.
set_rate
=
perclk3_set_rate
,
}
};
static
const
struct
clk
*
clko_clocks
[]
=
{
&
perclk
[
0
],
&
hclk
,
&
clk48m
,
&
clk16m
,
&
prem_clk
,
&
fclk
,
};
static
int
clko_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
int
i
;
unsigned
int
reg
;
i
=
_clk_can_use_parent
(
clko_clocks
,
ARRAY_SIZE
(
clko_clocks
),
parent
);
if
(
i
<
0
)
return
i
;
reg
=
__raw_readl
(
CCM_CSCR
)
&
~
CCM_CSCR_CLKO_MASK
;
reg
|=
i
<<
CCM_CSCR_CLKO_OFFSET
;
__raw_writel
(
reg
,
CCM_CSCR
);
if
(
clko_clocks
[
i
]
->
set_rate
&&
clko_clocks
[
i
]
->
round_rate
)
{
clk
->
set_rate
=
_clk_parent_set_rate
;
clk
->
round_rate
=
_clk_parent_round_rate
;
}
else
{
clk
->
set_rate
=
NULL
;
clk
->
round_rate
=
NULL
;
}
return
0
;
}
static
struct
clk
clko_clk
=
{
.
set_parent
=
clko_set_parent
,
};
static
struct
clk
dma_clk
=
{
.
parent
=
&
hclk
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
.
enable
=
_clk_enable
,
.
enable_reg
=
SCM_GCCR
,
.
enable_shift
=
SCM_GCCR_DMA_CLK_EN_OFFSET
,
.
disable
=
_clk_disable
,
};
static
struct
clk
csi_clk
=
{
.
parent
=
&
hclk
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
.
enable
=
_clk_enable
,
.
enable_reg
=
SCM_GCCR
,
.
enable_shift
=
SCM_GCCR_CSI_CLK_EN_OFFSET
,
.
disable
=
_clk_disable
,
};
static
struct
clk
mma_clk
=
{
.
parent
=
&
hclk
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
.
enable
=
_clk_enable
,
.
enable_reg
=
SCM_GCCR
,
.
enable_shift
=
SCM_GCCR_MMA_CLK_EN_OFFSET
,
.
disable
=
_clk_disable
,
};
static
struct
clk
usbd_clk
=
{
.
parent
=
&
clk48m
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
.
enable
=
_clk_enable
,
.
enable_reg
=
SCM_GCCR
,
.
enable_shift
=
SCM_GCCR_USBD_CLK_EN_OFFSET
,
.
disable
=
_clk_disable
,
};
static
struct
clk
gpt_clk
=
{
.
parent
=
&
perclk
[
0
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
uart_clk
=
{
.
parent
=
&
perclk
[
0
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
i2c_clk
=
{
.
parent
=
&
hclk
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
spi_clk
=
{
.
parent
=
&
perclk
[
1
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
sdhc_clk
=
{
.
parent
=
&
perclk
[
1
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
lcdc_clk
=
{
.
parent
=
&
perclk
[
1
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
mshc_clk
=
{
.
parent
=
&
hclk
,
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
ssi_clk
=
{
.
parent
=
&
perclk
[
2
],
.
round_rate
=
_clk_parent_round_rate
,
.
set_rate
=
_clk_parent_set_rate
,
};
static
struct
clk
rtc_clk
=
{
.
parent
=
&
clk32
,
};
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
},
static
struct
clk_lookup
lookups
[]
__initdata
=
{
_REGISTER_CLOCK
(
NULL
,
"dma"
,
dma_clk
)
_REGISTER_CLOCK
(
"mx1-camera.0"
,
NULL
,
csi_clk
)
_REGISTER_CLOCK
(
NULL
,
"mma"
,
mma_clk
)
_REGISTER_CLOCK
(
"imx_udc.0"
,
NULL
,
usbd_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpt"
,
gpt_clk
)
_REGISTER_CLOCK
(
"imx1-uart.0"
,
NULL
,
uart_clk
)
_REGISTER_CLOCK
(
"imx1-uart.1"
,
NULL
,
uart_clk
)
_REGISTER_CLOCK
(
"imx1-uart.2"
,
NULL
,
uart_clk
)
_REGISTER_CLOCK
(
"imx-i2c.0"
,
NULL
,
i2c_clk
)
_REGISTER_CLOCK
(
"imx1-cspi.0"
,
NULL
,
spi_clk
)
_REGISTER_CLOCK
(
"imx1-cspi.1"
,
NULL
,
spi_clk
)
_REGISTER_CLOCK
(
"imx-mmc.0"
,
NULL
,
sdhc_clk
)
_REGISTER_CLOCK
(
"imx-fb.0"
,
NULL
,
lcdc_clk
)
_REGISTER_CLOCK
(
NULL
,
"mshc"
,
mshc_clk
)
_REGISTER_CLOCK
(
NULL
,
"ssi"
,
ssi_clk
)
_REGISTER_CLOCK
(
"mxc_rtc.0"
,
NULL
,
rtc_clk
)
};
int
__init
mx1_clocks_init
(
unsigned
long
fref
)
{
unsigned
int
reg
;
/* disable clocks we are able to */
__raw_writel
(
0
,
SCM_GCCR
);
clk32_rate
=
fref
;
reg
=
__raw_readl
(
CCM_CSCR
);
/* detect clock reference for system PLL */
if
(
reg
&
CCM_CSCR_SYSTEM_SEL
)
{
prem_clk
.
parent
=
&
clk16m
;
}
else
{
/* ensure that oscillator is disabled */
reg
&=
~
(
1
<<
CCM_CSCR_OSC_EN_SHIFT
);
__raw_writel
(
reg
,
CCM_CSCR
);
prem_clk
.
parent
=
&
clk32_premult
;
}
/* detect reference for CLKO */
reg
=
(
reg
&
CCM_CSCR_CLKO_MASK
)
>>
CCM_CSCR_CLKO_OFFSET
;
clko_clk
.
parent
=
(
struct
clk
*
)
clko_clocks
[
reg
];
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
clk_enable
(
&
hclk
);
clk_enable
(
&
fclk
);
mxc_timer_init
(
&
gpt_clk
,
MX1_IO_ADDRESS
(
MX1_TIM1_BASE_ADDR
),
MX1_TIM1_INT
);
return
0
;
}
arch/arm/mach-imx/clock-imx21.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
此差异已折叠。
点击以展开。
arch/arm/mach-imx/clock-imx25.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
/*
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/mx25.h>
#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
#define CCM_MPCTL 0x00
#define CCM_UPCTL 0x04
#define CCM_CCTL 0x08
#define CCM_CGCR0 0x0C
#define CCM_CGCR1 0x10
#define CCM_CGCR2 0x14
#define CCM_PCDR0 0x18
#define CCM_PCDR1 0x1C
#define CCM_PCDR2 0x20
#define CCM_PCDR3 0x24
#define CCM_RCSR 0x28
#define CCM_CRDR 0x2C
#define CCM_DCVR0 0x30
#define CCM_DCVR1 0x34
#define CCM_DCVR2 0x38
#define CCM_DCVR3 0x3c
#define CCM_LTR0 0x40
#define CCM_LTR1 0x44
#define CCM_LTR2 0x48
#define CCM_LTR3 0x4c
static
unsigned
long
get_rate_mpll
(
void
)
{
ulong
mpctl
=
__raw_readl
(
CRM_BASE
+
CCM_MPCTL
);
return
mxc_decode_pll
(
mpctl
,
24000000
);
}
static
unsigned
long
get_rate_upll
(
void
)
{
ulong
mpctl
=
__raw_readl
(
CRM_BASE
+
CCM_UPCTL
);
return
mxc_decode_pll
(
mpctl
,
24000000
);
}
unsigned
long
get_rate_arm
(
struct
clk
*
clk
)
{
unsigned
long
cctl
=
readl
(
CRM_BASE
+
CCM_CCTL
);
unsigned
long
rate
=
get_rate_mpll
();
if
(
cctl
&
(
1
<<
14
))
rate
=
(
rate
*
3
)
>>
2
;
return
rate
/
((
cctl
>>
30
)
+
1
);
}
static
unsigned
long
get_rate_ahb
(
struct
clk
*
clk
)
{
unsigned
long
cctl
=
readl
(
CRM_BASE
+
CCM_CCTL
);
return
get_rate_arm
(
NULL
)
/
(((
cctl
>>
28
)
&
0x3
)
+
1
);
}
static
unsigned
long
get_rate_ipg
(
struct
clk
*
clk
)
{
return
get_rate_ahb
(
NULL
)
>>
1
;
}
static
unsigned
long
get_rate_per
(
int
per
)
{
unsigned
long
ofs
=
(
per
&
0x3
)
*
8
;
unsigned
long
reg
=
per
&
~
0x3
;
unsigned
long
val
=
(
readl
(
CRM_BASE
+
CCM_PCDR0
+
reg
)
>>
ofs
)
&
0x3f
;
unsigned
long
fref
;
if
(
readl
(
CRM_BASE
+
0x64
)
&
(
1
<<
per
))
fref
=
get_rate_upll
();
else
fref
=
get_rate_ahb
(
NULL
);
return
fref
/
(
val
+
1
);
}
static
unsigned
long
get_rate_uart
(
struct
clk
*
clk
)
{
return
get_rate_per
(
15
);
}
static
unsigned
long
get_rate_ssi2
(
struct
clk
*
clk
)
{
return
get_rate_per
(
14
);
}
static
unsigned
long
get_rate_ssi1
(
struct
clk
*
clk
)
{
return
get_rate_per
(
13
);
}
static
unsigned
long
get_rate_i2c
(
struct
clk
*
clk
)
{
return
get_rate_per
(
6
);
}
static
unsigned
long
get_rate_nfc
(
struct
clk
*
clk
)
{
return
get_rate_per
(
8
);
}
static
unsigned
long
get_rate_gpt
(
struct
clk
*
clk
)
{
return
get_rate_per
(
5
);
}
static
unsigned
long
get_rate_lcdc
(
struct
clk
*
clk
)
{
return
get_rate_per
(
7
);
}
static
unsigned
long
get_rate_esdhc1
(
struct
clk
*
clk
)
{
return
get_rate_per
(
3
);
}
static
unsigned
long
get_rate_esdhc2
(
struct
clk
*
clk
)
{
return
get_rate_per
(
4
);
}
static
unsigned
long
get_rate_csi
(
struct
clk
*
clk
)
{
return
get_rate_per
(
0
);
}
static
unsigned
long
get_rate_otg
(
struct
clk
*
clk
)
{
unsigned
long
cctl
=
readl
(
CRM_BASE
+
CCM_CCTL
);
unsigned
long
rate
=
get_rate_upll
();
return
(
cctl
&
(
1
<<
23
))
?
0
:
rate
/
((
0x3F
&
(
cctl
>>
16
))
+
1
);
}
static
int
clk_cgcr_enable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
|=
1
<<
clk
->
enable_shift
;
__raw_writel
(
reg
,
clk
->
enable_reg
);
return
0
;
}
static
void
clk_cgcr_disable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
&=
~
(
1
<<
clk
->
enable_shift
);
__raw_writel
(
reg
,
clk
->
enable_reg
);
}
#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
static struct clk name = { \
.id = i, \
.enable_reg = CRM_BASE + er, \
.enable_shift = es, \
.get_rate = gr, \
.set_rate = sr, \
.enable = clk_cgcr_enable, \
.disable = clk_cgcr_disable, \
.secondary = s, \
}
/*
* Note: the following IPG clock gating bits are wrongly marked "Reserved" in
* the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
* taken from the Freescale released BSP.
*
* bit reg offset clock
*
* 0 CGCR1 0 AUDMUX
* 12 CGCR1 12 ESAI
* 16 CGCR1 16 GPIO1
* 17 CGCR1 17 GPIO2
* 18 CGCR1 18 GPIO3
* 23 CGCR1 23 I2C1
* 24 CGCR1 24 I2C2
* 25 CGCR1 25 I2C3
* 27 CGCR1 27 IOMUXC
* 28 CGCR1 28 KPP
* 30 CGCR1 30 OWIRE
* 36 CGCR2 4 RTIC
* 51 CGCR2 19 WDOG
*/
DEFINE_CLOCK
(
gpt_clk
,
0
,
CCM_CGCR0
,
5
,
get_rate_gpt
,
NULL
,
NULL
);
DEFINE_CLOCK
(
uart_per_clk
,
0
,
CCM_CGCR0
,
15
,
get_rate_uart
,
NULL
,
NULL
);
DEFINE_CLOCK
(
ssi1_per_clk
,
0
,
CCM_CGCR0
,
13
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
ssi2_per_clk
,
0
,
CCM_CGCR0
,
14
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
cspi1_clk
,
0
,
CCM_CGCR1
,
5
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
cspi2_clk
,
0
,
CCM_CGCR1
,
6
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
cspi3_clk
,
0
,
CCM_CGCR1
,
7
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
esdhc1_ahb_clk
,
0
,
CCM_CGCR0
,
21
,
get_rate_esdhc1
,
NULL
,
NULL
);
DEFINE_CLOCK
(
esdhc1_per_clk
,
0
,
CCM_CGCR0
,
3
,
get_rate_esdhc1
,
NULL
,
&
esdhc1_ahb_clk
);
DEFINE_CLOCK
(
esdhc2_ahb_clk
,
0
,
CCM_CGCR0
,
22
,
get_rate_esdhc2
,
NULL
,
NULL
);
DEFINE_CLOCK
(
esdhc2_per_clk
,
0
,
CCM_CGCR0
,
4
,
get_rate_esdhc2
,
NULL
,
&
esdhc2_ahb_clk
);
DEFINE_CLOCK
(
sdma_ahb_clk
,
0
,
CCM_CGCR0
,
26
,
NULL
,
NULL
,
NULL
);
DEFINE_CLOCK
(
fec_ahb_clk
,
0
,
CCM_CGCR0
,
23
,
NULL
,
NULL
,
NULL
);
DEFINE_CLOCK
(
lcdc_ahb_clk
,
0
,
CCM_CGCR0
,
24
,
NULL
,
NULL
,
NULL
);
DEFINE_CLOCK
(
lcdc_per_clk
,
0
,
CCM_CGCR0
,
7
,
NULL
,
NULL
,
&
lcdc_ahb_clk
);
DEFINE_CLOCK
(
csi_ahb_clk
,
0
,
CCM_CGCR0
,
18
,
get_rate_csi
,
NULL
,
NULL
);
DEFINE_CLOCK
(
csi_per_clk
,
0
,
CCM_CGCR0
,
0
,
get_rate_csi
,
NULL
,
&
csi_ahb_clk
);
DEFINE_CLOCK
(
uart1_clk
,
0
,
CCM_CGCR2
,
14
,
get_rate_uart
,
NULL
,
&
uart_per_clk
);
DEFINE_CLOCK
(
uart2_clk
,
0
,
CCM_CGCR2
,
15
,
get_rate_uart
,
NULL
,
&
uart_per_clk
);
DEFINE_CLOCK
(
uart3_clk
,
0
,
CCM_CGCR2
,
16
,
get_rate_uart
,
NULL
,
&
uart_per_clk
);
DEFINE_CLOCK
(
uart4_clk
,
0
,
CCM_CGCR2
,
17
,
get_rate_uart
,
NULL
,
&
uart_per_clk
);
DEFINE_CLOCK
(
uart5_clk
,
0
,
CCM_CGCR2
,
18
,
get_rate_uart
,
NULL
,
&
uart_per_clk
);
DEFINE_CLOCK
(
nfc_clk
,
0
,
CCM_CGCR0
,
8
,
get_rate_nfc
,
NULL
,
NULL
);
DEFINE_CLOCK
(
usbotg_clk
,
0
,
CCM_CGCR0
,
28
,
get_rate_otg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
pwm1_clk
,
0
,
CCM_CGCR1
,
31
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
pwm2_clk
,
0
,
CCM_CGCR2
,
0
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
pwm3_clk
,
0
,
CCM_CGCR2
,
1
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
pwm4_clk
,
0
,
CCM_CGCR2
,
2
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
kpp_clk
,
0
,
CCM_CGCR1
,
28
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
tsc_clk
,
0
,
CCM_CGCR2
,
13
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
i2c_clk
,
0
,
CCM_CGCR0
,
6
,
get_rate_i2c
,
NULL
,
NULL
);
DEFINE_CLOCK
(
fec_clk
,
0
,
CCM_CGCR1
,
15
,
get_rate_ipg
,
NULL
,
&
fec_ahb_clk
);
DEFINE_CLOCK
(
dryice_clk
,
0
,
CCM_CGCR1
,
8
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
lcdc_clk
,
0
,
CCM_CGCR1
,
29
,
get_rate_lcdc
,
NULL
,
&
lcdc_per_clk
);
DEFINE_CLOCK
(
wdt_clk
,
0
,
CCM_CGCR2
,
19
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
ssi1_clk
,
0
,
CCM_CGCR2
,
11
,
get_rate_ssi1
,
NULL
,
&
ssi1_per_clk
);
DEFINE_CLOCK
(
ssi2_clk
,
1
,
CCM_CGCR2
,
12
,
get_rate_ssi2
,
NULL
,
&
ssi2_per_clk
);
DEFINE_CLOCK
(
sdma_clk
,
0
,
CCM_CGCR2
,
6
,
get_rate_ipg
,
NULL
,
&
sdma_ahb_clk
);
DEFINE_CLOCK
(
esdhc1_clk
,
0
,
CCM_CGCR1
,
13
,
get_rate_esdhc1
,
NULL
,
&
esdhc1_per_clk
);
DEFINE_CLOCK
(
esdhc2_clk
,
1
,
CCM_CGCR1
,
14
,
get_rate_esdhc2
,
NULL
,
&
esdhc2_per_clk
);
DEFINE_CLOCK
(
audmux_clk
,
0
,
CCM_CGCR1
,
0
,
NULL
,
NULL
,
NULL
);
DEFINE_CLOCK
(
csi_clk
,
0
,
CCM_CGCR1
,
4
,
get_rate_csi
,
NULL
,
&
csi_per_clk
);
DEFINE_CLOCK
(
can1_clk
,
0
,
CCM_CGCR1
,
2
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
can2_clk
,
1
,
CCM_CGCR1
,
3
,
get_rate_ipg
,
NULL
,
NULL
);
DEFINE_CLOCK
(
iim_clk
,
0
,
CCM_CGCR1
,
26
,
NULL
,
NULL
,
NULL
);
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
},
static
struct
clk_lookup
lookups
[]
=
{
/* i.mx25 has the i.mx21 type uart */
_REGISTER_CLOCK
(
"imx21-uart.0"
,
NULL
,
uart1_clk
)
_REGISTER_CLOCK
(
"imx21-uart.1"
,
NULL
,
uart2_clk
)
_REGISTER_CLOCK
(
"imx21-uart.2"
,
NULL
,
uart3_clk
)
_REGISTER_CLOCK
(
"imx21-uart.3"
,
NULL
,
uart4_clk
)
_REGISTER_CLOCK
(
"imx21-uart.4"
,
NULL
,
uart5_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.0"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.1"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.2"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"fsl-usb2-udc"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"mxc_nand.0"
,
NULL
,
nfc_clk
)
/* i.mx25 has the i.mx35 type cspi */
_REGISTER_CLOCK
(
"imx35-cspi.0"
,
NULL
,
cspi1_clk
)
_REGISTER_CLOCK
(
"imx35-cspi.1"
,
NULL
,
cspi2_clk
)
_REGISTER_CLOCK
(
"imx35-cspi.2"
,
NULL
,
cspi3_clk
)
_REGISTER_CLOCK
(
"mxc_pwm.0"
,
NULL
,
pwm1_clk
)
_REGISTER_CLOCK
(
"mxc_pwm.1"
,
NULL
,
pwm2_clk
)
_REGISTER_CLOCK
(
"mxc_pwm.2"
,
NULL
,
pwm3_clk
)
_REGISTER_CLOCK
(
"mxc_pwm.3"
,
NULL
,
pwm4_clk
)
_REGISTER_CLOCK
(
"imx-keypad"
,
NULL
,
kpp_clk
)
_REGISTER_CLOCK
(
"mx25-adc"
,
NULL
,
tsc_clk
)
_REGISTER_CLOCK
(
"imx-i2c.0"
,
NULL
,
i2c_clk
)
_REGISTER_CLOCK
(
"imx-i2c.1"
,
NULL
,
i2c_clk
)
_REGISTER_CLOCK
(
"imx-i2c.2"
,
NULL
,
i2c_clk
)
_REGISTER_CLOCK
(
"imx25-fec.0"
,
NULL
,
fec_clk
)
_REGISTER_CLOCK
(
"imxdi_rtc.0"
,
NULL
,
dryice_clk
)
_REGISTER_CLOCK
(
"imx-fb.0"
,
NULL
,
lcdc_clk
)
_REGISTER_CLOCK
(
"imx2-wdt.0"
,
NULL
,
wdt_clk
)
_REGISTER_CLOCK
(
"imx-ssi.0"
,
NULL
,
ssi1_clk
)
_REGISTER_CLOCK
(
"imx-ssi.1"
,
NULL
,
ssi2_clk
)
_REGISTER_CLOCK
(
"sdhci-esdhc-imx25.0"
,
NULL
,
esdhc1_clk
)
_REGISTER_CLOCK
(
"sdhci-esdhc-imx25.1"
,
NULL
,
esdhc2_clk
)
_REGISTER_CLOCK
(
"mx2-camera.0"
,
NULL
,
csi_clk
)
_REGISTER_CLOCK
(
NULL
,
"audmux"
,
audmux_clk
)
_REGISTER_CLOCK
(
"flexcan.0"
,
NULL
,
can1_clk
)
_REGISTER_CLOCK
(
"flexcan.1"
,
NULL
,
can2_clk
)
/* i.mx25 has the i.mx35 type sdma */
_REGISTER_CLOCK
(
"imx35-sdma"
,
NULL
,
sdma_clk
)
_REGISTER_CLOCK
(
NULL
,
"iim"
,
iim_clk
)
};
int
__init
mx25_clocks_init
(
void
)
{
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
/* Turn off all clocks except the ones we need to survive, namely:
* EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
* SCC
*/
__raw_writel
((
1
<<
19
),
CRM_BASE
+
CCM_CGCR0
);
__raw_writel
((
0xf
<<
16
)
|
(
3
<<
26
),
CRM_BASE
+
CCM_CGCR1
);
__raw_writel
((
1
<<
5
),
CRM_BASE
+
CCM_CGCR2
);
#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
clk_enable
(
&
uart1_clk
);
#endif
/* Clock source for lcdc and csi is upll */
__raw_writel
(
__raw_readl
(
CRM_BASE
+
0x64
)
|
(
1
<<
7
)
|
(
1
<<
0
),
CRM_BASE
+
0x64
);
/* Clock source for gpt is ahb_div */
__raw_writel
(
__raw_readl
(
CRM_BASE
+
0x64
)
&
~
(
1
<<
5
),
CRM_BASE
+
0x64
);
clk_enable
(
&
iim_clk
);
imx_print_silicon_rev
(
"i.MX25"
,
mx25_revision
());
clk_disable
(
&
iim_clk
);
mxc_timer_init
(
&
gpt_clk
,
MX25_IO_ADDRESS
(
MX25_GPT1_BASE_ADDR
),
54
);
return
0
;
}
arch/arm/mach-imx/clock-imx27.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
此差异已折叠。
点击以展开。
arch/arm/mach-imx/clock-imx31.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
/*
* Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/div64.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/mx31.h>
#include <mach/common.h>
#include "crmregs-imx3.h"
#define PRE_DIV_MIN_FREQ 10000000
/* Minimum Frequency after Predivider */
static
void
__calc_pre_post_dividers
(
u32
div
,
u32
*
pre
,
u32
*
post
)
{
u32
min_pre
,
temp_pre
,
old_err
,
err
;
if
(
div
>=
512
)
{
*
pre
=
8
;
*
post
=
64
;
}
else
if
(
div
>=
64
)
{
min_pre
=
(
div
-
1
)
/
64
+
1
;
old_err
=
8
;
for
(
temp_pre
=
8
;
temp_pre
>=
min_pre
;
temp_pre
--
)
{
err
=
div
%
temp_pre
;
if
(
err
==
0
)
{
*
pre
=
temp_pre
;
break
;
}
err
=
temp_pre
-
err
;
if
(
err
<
old_err
)
{
old_err
=
err
;
*
pre
=
temp_pre
;
}
}
*
post
=
(
div
+
*
pre
-
1
)
/
*
pre
;
}
else
if
(
div
<=
8
)
{
*
pre
=
div
;
*
post
=
1
;
}
else
{
*
pre
=
1
;
*
post
=
div
;
}
}
static
struct
clk
mcu_pll_clk
;
static
struct
clk
serial_pll_clk
;
static
struct
clk
ipg_clk
;
static
struct
clk
ckih_clk
;
static
int
cgr_enable
(
struct
clk
*
clk
)
{
u32
reg
;
if
(
!
clk
->
enable_reg
)
return
0
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
|=
3
<<
clk
->
enable_shift
;
__raw_writel
(
reg
,
clk
->
enable_reg
);
return
0
;
}
static
void
cgr_disable
(
struct
clk
*
clk
)
{
u32
reg
;
if
(
!
clk
->
enable_reg
)
return
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
&=
~
(
3
<<
clk
->
enable_shift
);
/* special case for EMI clock */
if
(
clk
->
enable_reg
==
MXC_CCM_CGR2
&&
clk
->
enable_shift
==
8
)
reg
|=
(
1
<<
clk
->
enable_shift
);
__raw_writel
(
reg
,
clk
->
enable_reg
);
}
static
unsigned
long
pll_ref_get_rate
(
void
)
{
unsigned
long
ccmr
;
unsigned
int
prcs
;
ccmr
=
__raw_readl
(
MXC_CCM_CCMR
);
prcs
=
(
ccmr
&
MXC_CCM_CCMR_PRCS_MASK
)
>>
MXC_CCM_CCMR_PRCS_OFFSET
;
if
(
prcs
==
0x1
)
return
CKIL_CLK_FREQ
*
1024
;
else
return
clk_get_rate
(
&
ckih_clk
);
}
static
unsigned
long
usb_pll_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
reg
;
reg
=
__raw_readl
(
MXC_CCM_UPCTL
);
return
mxc_decode_pll
(
reg
,
pll_ref_get_rate
());
}
static
unsigned
long
serial_pll_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
reg
;
reg
=
__raw_readl
(
MXC_CCM_SRPCTL
);
return
mxc_decode_pll
(
reg
,
pll_ref_get_rate
());
}
static
unsigned
long
mcu_pll_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
reg
,
ccmr
;
ccmr
=
__raw_readl
(
MXC_CCM_CCMR
);
if
(
!
(
ccmr
&
MXC_CCM_CCMR_MPE
)
||
(
ccmr
&
MXC_CCM_CCMR_MDS
))
return
clk_get_rate
(
&
ckih_clk
);
reg
=
__raw_readl
(
MXC_CCM_MPCTL
);
return
mxc_decode_pll
(
reg
,
pll_ref_get_rate
());
}
static
int
usb_pll_enable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
MXC_CCM_CCMR
);
reg
|=
MXC_CCM_CCMR_UPE
;
__raw_writel
(
reg
,
MXC_CCM_CCMR
);
/* No lock bit on MX31, so using max time from spec */
udelay
(
80
);
return
0
;
}
static
void
usb_pll_disable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
MXC_CCM_CCMR
);
reg
&=
~
MXC_CCM_CCMR_UPE
;
__raw_writel
(
reg
,
MXC_CCM_CCMR
);
}
static
int
serial_pll_enable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
MXC_CCM_CCMR
);
reg
|=
MXC_CCM_CCMR_SPE
;
__raw_writel
(
reg
,
MXC_CCM_CCMR
);
/* No lock bit on MX31, so using max time from spec */
udelay
(
80
);
return
0
;
}
static
void
serial_pll_disable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
MXC_CCM_CCMR
);
reg
&=
~
MXC_CCM_CCMR_SPE
;
__raw_writel
(
reg
,
MXC_CCM_CCMR
);
}
#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
static
unsigned
long
mcu_main_get_rate
(
struct
clk
*
clk
)
{
u32
pmcr0
=
__raw_readl
(
MXC_CCM_PMCR0
);
if
((
pmcr0
&
MXC_CCM_PMCR0_DFSUP1
)
==
MXC_CCM_PMCR0_DFSUP1_SPLL
)
return
clk_get_rate
(
&
serial_pll_clk
);
else
return
clk_get_rate
(
&
mcu_pll_clk
);
}
static
unsigned
long
ahb_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
max_pdf
;
max_pdf
=
PDR0
(
MXC_CCM_PDR0_MAX_PODF_MASK
,
MXC_CCM_PDR0_MAX_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
max_pdf
+
1
);
}
static
unsigned
long
ipg_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
ipg_pdf
;
ipg_pdf
=
PDR0
(
MXC_CCM_PDR0_IPG_PODF_MASK
,
MXC_CCM_PDR0_IPG_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
ipg_pdf
+
1
);
}
static
unsigned
long
nfc_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
nfc_pdf
;
nfc_pdf
=
PDR0
(
MXC_CCM_PDR0_NFC_PODF_MASK
,
MXC_CCM_PDR0_NFC_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
nfc_pdf
+
1
);
}
static
unsigned
long
hsp_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
hsp_pdf
;
hsp_pdf
=
PDR0
(
MXC_CCM_PDR0_HSP_PODF_MASK
,
MXC_CCM_PDR0_HSP_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
hsp_pdf
+
1
);
}
static
unsigned
long
usb_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
usb_pdf
,
usb_prepdf
;
usb_pdf
=
PDR1
(
MXC_CCM_PDR1_USB_PODF_MASK
,
MXC_CCM_PDR1_USB_PODF_OFFSET
);
usb_prepdf
=
PDR1
(
MXC_CCM_PDR1_USB_PRDF_MASK
,
MXC_CCM_PDR1_USB_PRDF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
usb_prepdf
+
1
)
/
(
usb_pdf
+
1
);
}
static
unsigned
long
csi_get_rate
(
struct
clk
*
clk
)
{
u32
reg
,
pre
,
post
;
reg
=
__raw_readl
(
MXC_CCM_PDR0
);
pre
=
(
reg
&
MXC_CCM_PDR0_CSI_PRDF_MASK
)
>>
MXC_CCM_PDR0_CSI_PRDF_OFFSET
;
pre
++
;
post
=
(
reg
&
MXC_CCM_PDR0_CSI_PODF_MASK
)
>>
MXC_CCM_PDR0_CSI_PODF_OFFSET
;
post
++
;
return
clk_get_rate
(
clk
->
parent
)
/
(
pre
*
post
);
}
static
unsigned
long
csi_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
pre
,
post
,
parent
=
clk_get_rate
(
clk
->
parent
);
u32
div
=
parent
/
rate
;
if
(
parent
%
rate
)
div
++
;
__calc_pre_post_dividers
(
div
,
&
pre
,
&
post
);
return
parent
/
(
pre
*
post
);
}
static
int
csi_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
reg
,
div
,
pre
,
post
,
parent
=
clk_get_rate
(
clk
->
parent
);
div
=
parent
/
rate
;
if
((
parent
/
div
)
!=
rate
)
return
-
EINVAL
;
__calc_pre_post_dividers
(
div
,
&
pre
,
&
post
);
/* Set CSI clock divider */
reg
=
__raw_readl
(
MXC_CCM_PDR0
)
&
~
(
MXC_CCM_PDR0_CSI_PODF_MASK
|
MXC_CCM_PDR0_CSI_PRDF_MASK
);
reg
|=
(
post
-
1
)
<<
MXC_CCM_PDR0_CSI_PODF_OFFSET
;
reg
|=
(
pre
-
1
)
<<
MXC_CCM_PDR0_CSI_PRDF_OFFSET
;
__raw_writel
(
reg
,
MXC_CCM_PDR0
);
return
0
;
}
static
unsigned
long
ssi1_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
ssi1_pdf
,
ssi1_prepdf
;
ssi1_pdf
=
PDR1
(
MXC_CCM_PDR1_SSI1_PODF_MASK
,
MXC_CCM_PDR1_SSI1_PODF_OFFSET
);
ssi1_prepdf
=
PDR1
(
MXC_CCM_PDR1_SSI1_PRE_PODF_MASK
,
MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
ssi1_prepdf
+
1
)
/
(
ssi1_pdf
+
1
);
}
static
unsigned
long
ssi2_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
ssi2_pdf
,
ssi2_prepdf
;
ssi2_pdf
=
PDR1
(
MXC_CCM_PDR1_SSI2_PODF_MASK
,
MXC_CCM_PDR1_SSI2_PODF_OFFSET
);
ssi2_prepdf
=
PDR1
(
MXC_CCM_PDR1_SSI2_PRE_PODF_MASK
,
MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
ssi2_prepdf
+
1
)
/
(
ssi2_pdf
+
1
);
}
static
unsigned
long
firi_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
firi_pdf
,
firi_prepdf
;
firi_pdf
=
PDR1
(
MXC_CCM_PDR1_FIRI_PODF_MASK
,
MXC_CCM_PDR1_FIRI_PODF_OFFSET
);
firi_prepdf
=
PDR1
(
MXC_CCM_PDR1_FIRI_PRE_PODF_MASK
,
MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
firi_prepdf
+
1
)
/
(
firi_pdf
+
1
);
}
static
unsigned
long
firi_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
pre
,
post
;
u32
parent
=
clk_get_rate
(
clk
->
parent
);
u32
div
=
parent
/
rate
;
if
(
parent
%
rate
)
div
++
;
__calc_pre_post_dividers
(
div
,
&
pre
,
&
post
);
return
parent
/
(
pre
*
post
);
}
static
int
firi_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
reg
,
div
,
pre
,
post
,
parent
=
clk_get_rate
(
clk
->
parent
);
div
=
parent
/
rate
;
if
((
parent
/
div
)
!=
rate
)
return
-
EINVAL
;
__calc_pre_post_dividers
(
div
,
&
pre
,
&
post
);
/* Set FIRI clock divider */
reg
=
__raw_readl
(
MXC_CCM_PDR1
)
&
~
(
MXC_CCM_PDR1_FIRI_PODF_MASK
|
MXC_CCM_PDR1_FIRI_PRE_PODF_MASK
);
reg
|=
(
pre
-
1
)
<<
MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET
;
reg
|=
(
post
-
1
)
<<
MXC_CCM_PDR1_FIRI_PODF_OFFSET
;
__raw_writel
(
reg
,
MXC_CCM_PDR1
);
return
0
;
}
static
unsigned
long
mbx_get_rate
(
struct
clk
*
clk
)
{
return
clk_get_rate
(
clk
->
parent
)
/
2
;
}
static
unsigned
long
mstick1_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
msti_pdf
;
msti_pdf
=
PDR2
(
MXC_CCM_PDR2_MST1_PDF_MASK
,
MXC_CCM_PDR2_MST1_PDF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
msti_pdf
+
1
);
}
static
unsigned
long
mstick2_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
msti_pdf
;
msti_pdf
=
PDR2
(
MXC_CCM_PDR2_MST2_PDF_MASK
,
MXC_CCM_PDR2_MST2_PDF_OFFSET
);
return
clk_get_rate
(
clk
->
parent
)
/
(
msti_pdf
+
1
);
}
static
unsigned
long
ckih_rate
;
static
unsigned
long
clk_ckih_get_rate
(
struct
clk
*
clk
)
{
return
ckih_rate
;
}
static
unsigned
long
clk_ckil_get_rate
(
struct
clk
*
clk
)
{
return
CKIL_CLK_FREQ
;
}
static
struct
clk
ckih_clk
=
{
.
get_rate
=
clk_ckih_get_rate
,
};
static
struct
clk
mcu_pll_clk
=
{
.
parent
=
&
ckih_clk
,
.
get_rate
=
mcu_pll_get_rate
,
};
static
struct
clk
mcu_main_clk
=
{
.
parent
=
&
mcu_pll_clk
,
.
get_rate
=
mcu_main_get_rate
,
};
static
struct
clk
serial_pll_clk
=
{
.
parent
=
&
ckih_clk
,
.
get_rate
=
serial_pll_get_rate
,
.
enable
=
serial_pll_enable
,
.
disable
=
serial_pll_disable
,
};
static
struct
clk
usb_pll_clk
=
{
.
parent
=
&
ckih_clk
,
.
get_rate
=
usb_pll_get_rate
,
.
enable
=
usb_pll_enable
,
.
disable
=
usb_pll_disable
,
};
static
struct
clk
ahb_clk
=
{
.
parent
=
&
mcu_main_clk
,
.
get_rate
=
ahb_get_rate
,
};
#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
static struct clk name = { \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
.get_rate = gr, \
.enable = cgr_enable, \
.disable = cgr_disable, \
.secondary = s, \
.parent = p, \
}
#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
static struct clk name = { \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
.get_rate = getsetround##_get_rate, \
.set_rate = getsetround##_set_rate, \
.round_rate = getsetround##_round_rate, \
.enable = cgr_enable, \
.disable = cgr_disable, \
.secondary = s, \
.parent = p, \
}
DEFINE_CLOCK
(
perclk_clk
,
0
,
NULL
,
0
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
ckil_clk
,
0
,
NULL
,
0
,
clk_ckil_get_rate
,
NULL
,
NULL
);
DEFINE_CLOCK
(
sdhc1_clk
,
0
,
MXC_CCM_CGR0
,
0
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
sdhc2_clk
,
1
,
MXC_CCM_CGR0
,
2
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
gpt_clk
,
0
,
MXC_CCM_CGR0
,
4
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
epit1_clk
,
0
,
MXC_CCM_CGR0
,
6
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
epit2_clk
,
1
,
MXC_CCM_CGR0
,
8
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
iim_clk
,
0
,
MXC_CCM_CGR0
,
10
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
pata_clk
,
0
,
MXC_CCM_CGR0
,
12
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
sdma_clk1
,
0
,
MXC_CCM_CGR0
,
14
,
NULL
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
cspi3_clk
,
2
,
MXC_CCM_CGR0
,
16
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
rng_clk
,
0
,
MXC_CCM_CGR0
,
18
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
uart1_clk
,
0
,
MXC_CCM_CGR0
,
20
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
uart2_clk
,
1
,
MXC_CCM_CGR0
,
22
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
ssi1_clk
,
0
,
MXC_CCM_CGR0
,
24
,
ssi1_get_rate
,
NULL
,
&
serial_pll_clk
);
DEFINE_CLOCK
(
i2c1_clk
,
0
,
MXC_CCM_CGR0
,
26
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
i2c2_clk
,
1
,
MXC_CCM_CGR0
,
28
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
i2c3_clk
,
2
,
MXC_CCM_CGR0
,
30
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
mpeg4_clk
,
0
,
MXC_CCM_CGR1
,
0
,
NULL
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
mstick1_clk
,
0
,
MXC_CCM_CGR1
,
2
,
mstick1_get_rate
,
NULL
,
&
usb_pll_clk
);
DEFINE_CLOCK
(
mstick2_clk
,
1
,
MXC_CCM_CGR1
,
4
,
mstick2_get_rate
,
NULL
,
&
usb_pll_clk
);
DEFINE_CLOCK1
(
csi_clk
,
0
,
MXC_CCM_CGR1
,
6
,
csi
,
NULL
,
&
serial_pll_clk
);
DEFINE_CLOCK
(
rtc_clk
,
0
,
MXC_CCM_CGR1
,
8
,
NULL
,
NULL
,
&
ckil_clk
);
DEFINE_CLOCK
(
wdog_clk
,
0
,
MXC_CCM_CGR1
,
10
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
pwm_clk
,
0
,
MXC_CCM_CGR1
,
12
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
usb_clk2
,
0
,
MXC_CCM_CGR1
,
18
,
usb_get_rate
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
kpp_clk
,
0
,
MXC_CCM_CGR1
,
20
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
ipu_clk
,
0
,
MXC_CCM_CGR1
,
22
,
hsp_get_rate
,
NULL
,
&
mcu_main_clk
);
DEFINE_CLOCK
(
uart3_clk
,
2
,
MXC_CCM_CGR1
,
24
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
uart4_clk
,
3
,
MXC_CCM_CGR1
,
26
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
uart5_clk
,
4
,
MXC_CCM_CGR1
,
28
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
owire_clk
,
0
,
MXC_CCM_CGR1
,
30
,
NULL
,
NULL
,
&
perclk_clk
);
DEFINE_CLOCK
(
ssi2_clk
,
1
,
MXC_CCM_CGR2
,
0
,
ssi2_get_rate
,
NULL
,
&
serial_pll_clk
);
DEFINE_CLOCK
(
cspi1_clk
,
0
,
MXC_CCM_CGR2
,
2
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
cspi2_clk
,
1
,
MXC_CCM_CGR2
,
4
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
mbx_clk
,
0
,
MXC_CCM_CGR2
,
6
,
mbx_get_rate
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
emi_clk
,
0
,
MXC_CCM_CGR2
,
8
,
NULL
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
rtic_clk
,
0
,
MXC_CCM_CGR2
,
10
,
NULL
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK1
(
firi_clk
,
0
,
MXC_CCM_CGR2
,
12
,
firi
,
NULL
,
&
usb_pll_clk
);
DEFINE_CLOCK
(
sdma_clk2
,
0
,
NULL
,
0
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
usb_clk1
,
0
,
NULL
,
0
,
usb_get_rate
,
NULL
,
&
usb_pll_clk
);
DEFINE_CLOCK
(
nfc_clk
,
0
,
NULL
,
0
,
nfc_get_rate
,
NULL
,
&
ahb_clk
);
DEFINE_CLOCK
(
scc_clk
,
0
,
NULL
,
0
,
NULL
,
NULL
,
&
ipg_clk
);
DEFINE_CLOCK
(
ipg_clk
,
0
,
NULL
,
0
,
ipg_get_rate
,
NULL
,
&
ahb_clk
);
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
},
static
struct
clk_lookup
lookups
[]
=
{
_REGISTER_CLOCK
(
NULL
,
"emi"
,
emi_clk
)
_REGISTER_CLOCK
(
"imx31-cspi.0"
,
NULL
,
cspi1_clk
)
_REGISTER_CLOCK
(
"imx31-cspi.1"
,
NULL
,
cspi2_clk
)
_REGISTER_CLOCK
(
"imx31-cspi.2"
,
NULL
,
cspi3_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpt"
,
gpt_clk
)
_REGISTER_CLOCK
(
NULL
,
"pwm"
,
pwm_clk
)
_REGISTER_CLOCK
(
"imx2-wdt.0"
,
NULL
,
wdog_clk
)
_REGISTER_CLOCK
(
NULL
,
"rtc"
,
rtc_clk
)
_REGISTER_CLOCK
(
NULL
,
"epit"
,
epit1_clk
)
_REGISTER_CLOCK
(
NULL
,
"epit"
,
epit2_clk
)
_REGISTER_CLOCK
(
"mxc_nand.0"
,
NULL
,
nfc_clk
)
_REGISTER_CLOCK
(
"ipu-core"
,
NULL
,
ipu_clk
)
_REGISTER_CLOCK
(
"mx3_sdc_fb"
,
NULL
,
ipu_clk
)
_REGISTER_CLOCK
(
NULL
,
"kpp"
,
kpp_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.0"
,
"usb"
,
usb_clk1
)
_REGISTER_CLOCK
(
"mxc-ehci.0"
,
"usb_ahb"
,
usb_clk2
)
_REGISTER_CLOCK
(
"mxc-ehci.1"
,
"usb"
,
usb_clk1
)
_REGISTER_CLOCK
(
"mxc-ehci.1"
,
"usb_ahb"
,
usb_clk2
)
_REGISTER_CLOCK
(
"mxc-ehci.2"
,
"usb"
,
usb_clk1
)
_REGISTER_CLOCK
(
"mxc-ehci.2"
,
"usb_ahb"
,
usb_clk2
)
_REGISTER_CLOCK
(
"fsl-usb2-udc"
,
"usb"
,
usb_clk1
)
_REGISTER_CLOCK
(
"fsl-usb2-udc"
,
"usb_ahb"
,
usb_clk2
)
_REGISTER_CLOCK
(
"mx3-camera.0"
,
NULL
,
csi_clk
)
/* i.mx31 has the i.mx21 type uart */
_REGISTER_CLOCK
(
"imx21-uart.0"
,
NULL
,
uart1_clk
)
_REGISTER_CLOCK
(
"imx21-uart.1"
,
NULL
,
uart2_clk
)
_REGISTER_CLOCK
(
"imx21-uart.2"
,
NULL
,
uart3_clk
)
_REGISTER_CLOCK
(
"imx21-uart.3"
,
NULL
,
uart4_clk
)
_REGISTER_CLOCK
(
"imx21-uart.4"
,
NULL
,
uart5_clk
)
_REGISTER_CLOCK
(
"imx-i2c.0"
,
NULL
,
i2c1_clk
)
_REGISTER_CLOCK
(
"imx-i2c.1"
,
NULL
,
i2c2_clk
)
_REGISTER_CLOCK
(
"imx-i2c.2"
,
NULL
,
i2c3_clk
)
_REGISTER_CLOCK
(
"mxc_w1.0"
,
NULL
,
owire_clk
)
_REGISTER_CLOCK
(
"mxc-mmc.0"
,
NULL
,
sdhc1_clk
)
_REGISTER_CLOCK
(
"mxc-mmc.1"
,
NULL
,
sdhc2_clk
)
_REGISTER_CLOCK
(
"imx-ssi.0"
,
NULL
,
ssi1_clk
)
_REGISTER_CLOCK
(
"imx-ssi.1"
,
NULL
,
ssi2_clk
)
_REGISTER_CLOCK
(
NULL
,
"firi"
,
firi_clk
)
_REGISTER_CLOCK
(
"pata_imx"
,
NULL
,
pata_clk
)
_REGISTER_CLOCK
(
NULL
,
"rtic"
,
rtic_clk
)
_REGISTER_CLOCK
(
NULL
,
"rng"
,
rng_clk
)
_REGISTER_CLOCK
(
"imx31-sdma"
,
NULL
,
sdma_clk1
)
_REGISTER_CLOCK
(
NULL
,
"sdma_ipg"
,
sdma_clk2
)
_REGISTER_CLOCK
(
NULL
,
"mstick"
,
mstick1_clk
)
_REGISTER_CLOCK
(
NULL
,
"mstick"
,
mstick2_clk
)
_REGISTER_CLOCK
(
NULL
,
"scc"
,
scc_clk
)
_REGISTER_CLOCK
(
NULL
,
"iim"
,
iim_clk
)
_REGISTER_CLOCK
(
NULL
,
"mpeg4"
,
mpeg4_clk
)
_REGISTER_CLOCK
(
NULL
,
"mbx"
,
mbx_clk
)
};
int
__init
mx31_clocks_init
(
unsigned
long
fref
)
{
u32
reg
;
ckih_rate
=
fref
;
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
/* change the csi_clk parent if necessary */
reg
=
__raw_readl
(
MXC_CCM_CCMR
);
if
(
!
(
reg
&
MXC_CCM_CCMR_CSCS
))
if
(
clk_set_parent
(
&
csi_clk
,
&
usb_pll_clk
))
pr_err
(
"%s: error changing csi_clk parent
\n
"
,
__func__
);
/* Turn off all possible clocks */
__raw_writel
((
3
<<
4
),
MXC_CCM_CGR0
);
__raw_writel
(
0
,
MXC_CCM_CGR1
);
__raw_writel
((
3
<<
8
)
|
(
3
<<
14
)
|
(
3
<<
16
)
|
1
<<
27
|
1
<<
28
,
/* Bit 27 and 28 are not defined for
MX32, but still required to be set */
MXC_CCM_CGR2
);
/*
* Before turning off usb_pll make sure ipg_per_clk is generated
* by ipg_clk and not usb_pll.
*/
__raw_writel
(
__raw_readl
(
MXC_CCM_CCMR
)
|
(
1
<<
24
),
MXC_CCM_CCMR
);
usb_pll_disable
(
&
usb_pll_clk
);
pr_info
(
"Clock input source is %ld
\n
"
,
clk_get_rate
(
&
ckih_clk
));
clk_enable
(
&
gpt_clk
);
clk_enable
(
&
emi_clk
);
clk_enable
(
&
iim_clk
);
mx31_revision
();
clk_disable
(
&
iim_clk
);
clk_enable
(
&
serial_pll_clk
);
if
(
mx31_revision
()
>=
IMX_CHIP_REVISION_2_0
)
{
reg
=
__raw_readl
(
MXC_CCM_PMCR1
);
/* No PLL restart on DVFS switch; enable auto EMI handshake */
reg
|=
MXC_CCM_PMCR1_PLLRDIS
|
MXC_CCM_PMCR1_EMIRQ_EN
;
__raw_writel
(
reg
,
MXC_CCM_PMCR1
);
}
mxc_timer_init
(
&
ipg_clk
,
MX31_IO_ADDRESS
(
MX31_GPT1_BASE_ADDR
),
MX31_INT_GPT
);
return
0
;
}
arch/arm/mach-imx/clock-imx35.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
/*
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include "crmregs-imx3.h"
#ifdef HAVE_SET_RATE_SUPPORT
static
void
calc_dividers
(
u32
div
,
u32
*
pre
,
u32
*
post
,
u32
maxpost
)
{
u32
min_pre
,
temp_pre
,
old_err
,
err
;
min_pre
=
(
div
-
1
)
/
maxpost
+
1
;
old_err
=
8
;
for
(
temp_pre
=
8
;
temp_pre
>=
min_pre
;
temp_pre
--
)
{
if
(
div
>
(
temp_pre
*
maxpost
))
break
;
if
(
div
<
(
temp_pre
*
temp_pre
))
continue
;
err
=
div
%
temp_pre
;
if
(
err
==
0
)
{
*
pre
=
temp_pre
;
break
;
}
err
=
temp_pre
-
err
;
if
(
err
<
old_err
)
{
old_err
=
err
;
*
pre
=
temp_pre
;
}
}
*
post
=
(
div
+
*
pre
-
1
)
/
*
pre
;
}
/* get the best values for a 3-bit divider combined with a 6-bit divider */
static
void
calc_dividers_3_6
(
u32
div
,
u32
*
pre
,
u32
*
post
)
{
if
(
div
>=
512
)
{
*
pre
=
8
;
*
post
=
64
;
}
else
if
(
div
>=
64
)
{
calc_dividers
(
div
,
pre
,
post
,
64
);
}
else
if
(
div
<=
8
)
{
*
pre
=
div
;
*
post
=
1
;
}
else
{
*
pre
=
1
;
*
post
=
div
;
}
}
/* get the best values for two cascaded 3-bit dividers */
static
void
calc_dividers_3_3
(
u32
div
,
u32
*
pre
,
u32
*
post
)
{
if
(
div
>=
64
)
{
*
pre
=
*
post
=
8
;
}
else
if
(
div
>
8
)
{
calc_dividers
(
div
,
pre
,
post
,
8
);
}
else
{
*
pre
=
1
;
*
post
=
div
;
}
}
#endif
static
unsigned
long
get_rate_mpll
(
void
)
{
ulong
mpctl
=
__raw_readl
(
MX35_CCM_MPCTL
);
return
mxc_decode_pll
(
mpctl
,
24000000
);
}
static
unsigned
long
get_rate_ppll
(
void
)
{
ulong
ppctl
=
__raw_readl
(
MX35_CCM_PPCTL
);
return
mxc_decode_pll
(
ppctl
,
24000000
);
}
struct
arm_ahb_div
{
unsigned
char
arm
,
ahb
,
sel
;
};
static
struct
arm_ahb_div
clk_consumer
[]
=
{
{
.
arm
=
1
,
.
ahb
=
4
,
.
sel
=
0
},
{
.
arm
=
1
,
.
ahb
=
3
,
.
sel
=
1
},
{
.
arm
=
2
,
.
ahb
=
2
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
4
,
.
ahb
=
1
,
.
sel
=
0
},
{
.
arm
=
1
,
.
ahb
=
5
,
.
sel
=
0
},
{
.
arm
=
1
,
.
ahb
=
8
,
.
sel
=
0
},
{
.
arm
=
1
,
.
ahb
=
6
,
.
sel
=
1
},
{
.
arm
=
2
,
.
ahb
=
4
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
{
.
arm
=
4
,
.
ahb
=
2
,
.
sel
=
0
},
{
.
arm
=
0
,
.
ahb
=
0
,
.
sel
=
0
},
};
static
unsigned
long
get_rate_arm
(
void
)
{
unsigned
long
pdr0
=
__raw_readl
(
MXC_CCM_PDR0
);
struct
arm_ahb_div
*
aad
;
unsigned
long
fref
=
get_rate_mpll
();
aad
=
&
clk_consumer
[(
pdr0
>>
16
)
&
0xf
];
if
(
aad
->
sel
)
fref
=
fref
*
3
/
4
;
return
fref
/
aad
->
arm
;
}
static
unsigned
long
get_rate_ahb
(
struct
clk
*
clk
)
{
unsigned
long
pdr0
=
__raw_readl
(
MXC_CCM_PDR0
);
struct
arm_ahb_div
*
aad
;
unsigned
long
fref
=
get_rate_arm
();
aad
=
&
clk_consumer
[(
pdr0
>>
16
)
&
0xf
];
return
fref
/
aad
->
ahb
;
}
static
unsigned
long
get_rate_ipg
(
struct
clk
*
clk
)
{
return
get_rate_ahb
(
NULL
)
>>
1
;
}
static
unsigned
long
get_rate_uart
(
struct
clk
*
clk
)
{
unsigned
long
pdr3
=
__raw_readl
(
MX35_CCM_PDR3
);
unsigned
long
pdr4
=
__raw_readl
(
MX35_CCM_PDR4
);
unsigned
long
div
=
((
pdr4
>>
10
)
&
0x3f
)
+
1
;
if
(
pdr3
&
(
1
<<
14
))
return
get_rate_arm
()
/
div
;
else
return
get_rate_ppll
()
/
div
;
}
static
unsigned
long
get_rate_sdhc
(
struct
clk
*
clk
)
{
unsigned
long
pdr3
=
__raw_readl
(
MX35_CCM_PDR3
);
unsigned
long
div
,
rate
;
if
(
pdr3
&
(
1
<<
6
))
rate
=
get_rate_arm
();
else
rate
=
get_rate_ppll
();
switch
(
clk
->
id
)
{
default:
case
0
:
div
=
pdr3
&
0x3f
;
break
;
case
1
:
div
=
(
pdr3
>>
8
)
&
0x3f
;
break
;
case
2
:
div
=
(
pdr3
>>
16
)
&
0x3f
;
break
;
}
return
rate
/
(
div
+
1
);
}
static
unsigned
long
get_rate_mshc
(
struct
clk
*
clk
)
{
unsigned
long
pdr1
=
__raw_readl
(
MXC_CCM_PDR1
);
unsigned
long
div1
,
div2
,
rate
;
if
(
pdr1
&
(
1
<<
7
))
rate
=
get_rate_arm
();
else
rate
=
get_rate_ppll
();
div1
=
(
pdr1
>>
29
)
&
0x7
;
div2
=
(
pdr1
>>
22
)
&
0x3f
;
return
rate
/
((
div1
+
1
)
*
(
div2
+
1
));
}
static
unsigned
long
get_rate_ssi
(
struct
clk
*
clk
)
{
unsigned
long
pdr2
=
__raw_readl
(
MX35_CCM_PDR2
);
unsigned
long
div1
,
div2
,
rate
;
if
(
pdr2
&
(
1
<<
6
))
rate
=
get_rate_arm
();
else
rate
=
get_rate_ppll
();
switch
(
clk
->
id
)
{
default:
case
0
:
div1
=
pdr2
&
0x3f
;
div2
=
(
pdr2
>>
24
)
&
0x7
;
break
;
case
1
:
div1
=
(
pdr2
>>
8
)
&
0x3f
;
div2
=
(
pdr2
>>
27
)
&
0x7
;
break
;
}
return
rate
/
((
div1
+
1
)
*
(
div2
+
1
));
}
static
unsigned
long
get_rate_csi
(
struct
clk
*
clk
)
{
unsigned
long
pdr2
=
__raw_readl
(
MX35_CCM_PDR2
);
unsigned
long
rate
;
if
(
pdr2
&
(
1
<<
7
))
rate
=
get_rate_arm
();
else
rate
=
get_rate_ppll
();
return
rate
/
(((
pdr2
>>
16
)
&
0x3f
)
+
1
);
}
static
unsigned
long
get_rate_otg
(
struct
clk
*
clk
)
{
unsigned
long
pdr4
=
__raw_readl
(
MX35_CCM_PDR4
);
unsigned
long
rate
;
if
(
pdr4
&
(
1
<<
9
))
rate
=
get_rate_arm
();
else
rate
=
get_rate_ppll
();
return
rate
/
(((
pdr4
>>
22
)
&
0x3f
)
+
1
);
}
static
unsigned
long
get_rate_ipg_per
(
struct
clk
*
clk
)
{
unsigned
long
pdr0
=
__raw_readl
(
MXC_CCM_PDR0
);
unsigned
long
pdr4
=
__raw_readl
(
MX35_CCM_PDR4
);
unsigned
long
div
;
if
(
pdr0
&
(
1
<<
26
))
{
div
=
(
pdr4
>>
16
)
&
0x3f
;
return
get_rate_arm
()
/
(
div
+
1
);
}
else
{
div
=
(
pdr0
>>
12
)
&
0x7
;
return
get_rate_ahb
(
NULL
)
/
(
div
+
1
);
}
}
static
unsigned
long
get_rate_hsp
(
struct
clk
*
clk
)
{
unsigned
long
hsp_podf
=
(
__raw_readl
(
MXC_CCM_PDR0
)
>>
20
)
&
0x03
;
unsigned
long
fref
=
get_rate_mpll
();
if
(
fref
>
400
*
1000
*
1000
)
{
switch
(
hsp_podf
)
{
case
0
:
return
fref
>>
2
;
case
1
:
return
fref
>>
3
;
case
2
:
return
fref
/
3
;
}
}
else
{
switch
(
hsp_podf
)
{
case
0
:
case
2
:
return
fref
/
3
;
case
1
:
return
fref
/
6
;
}
}
return
0
;
}
static
int
clk_cgr_enable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
|=
3
<<
clk
->
enable_shift
;
__raw_writel
(
reg
,
clk
->
enable_reg
);
return
0
;
}
static
void
clk_cgr_disable
(
struct
clk
*
clk
)
{
u32
reg
;
reg
=
__raw_readl
(
clk
->
enable_reg
);
reg
&=
~
(
3
<<
clk
->
enable_shift
);
__raw_writel
(
reg
,
clk
->
enable_reg
);
}
#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
static struct clk name = { \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
.get_rate = gr, \
.set_rate = sr, \
.enable = clk_cgr_enable, \
.disable = clk_cgr_disable, \
}
DEFINE_CLOCK
(
asrc_clk
,
0
,
MX35_CCM_CGR0
,
0
,
NULL
,
NULL
);
DEFINE_CLOCK
(
pata_clk
,
0
,
MX35_CCM_CGR0
,
2
,
get_rate_ipg
,
NULL
);
/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */
DEFINE_CLOCK
(
can1_clk
,
0
,
MX35_CCM_CGR0
,
6
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
can2_clk
,
1
,
MX35_CCM_CGR0
,
8
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
cspi1_clk
,
0
,
MX35_CCM_CGR0
,
10
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
cspi2_clk
,
1
,
MX35_CCM_CGR0
,
12
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
ect_clk
,
0
,
MX35_CCM_CGR0
,
14
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
edio_clk
,
0
,
MX35_CCM_CGR0
,
16
,
NULL
,
NULL
);
DEFINE_CLOCK
(
emi_clk
,
0
,
MX35_CCM_CGR0
,
18
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
epit1_clk
,
0
,
MX35_CCM_CGR0
,
20
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
epit2_clk
,
1
,
MX35_CCM_CGR0
,
22
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
esai_clk
,
0
,
MX35_CCM_CGR0
,
24
,
NULL
,
NULL
);
DEFINE_CLOCK
(
esdhc1_clk
,
0
,
MX35_CCM_CGR0
,
26
,
get_rate_sdhc
,
NULL
);
DEFINE_CLOCK
(
esdhc2_clk
,
1
,
MX35_CCM_CGR0
,
28
,
get_rate_sdhc
,
NULL
);
DEFINE_CLOCK
(
esdhc3_clk
,
2
,
MX35_CCM_CGR0
,
30
,
get_rate_sdhc
,
NULL
);
DEFINE_CLOCK
(
fec_clk
,
0
,
MX35_CCM_CGR1
,
0
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
gpio1_clk
,
0
,
MX35_CCM_CGR1
,
2
,
NULL
,
NULL
);
DEFINE_CLOCK
(
gpio2_clk
,
1
,
MX35_CCM_CGR1
,
4
,
NULL
,
NULL
);
DEFINE_CLOCK
(
gpio3_clk
,
2
,
MX35_CCM_CGR1
,
6
,
NULL
,
NULL
);
DEFINE_CLOCK
(
gpt_clk
,
0
,
MX35_CCM_CGR1
,
8
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
i2c1_clk
,
0
,
MX35_CCM_CGR1
,
10
,
get_rate_ipg_per
,
NULL
);
DEFINE_CLOCK
(
i2c2_clk
,
1
,
MX35_CCM_CGR1
,
12
,
get_rate_ipg_per
,
NULL
);
DEFINE_CLOCK
(
i2c3_clk
,
2
,
MX35_CCM_CGR1
,
14
,
get_rate_ipg_per
,
NULL
);
DEFINE_CLOCK
(
iomuxc_clk
,
0
,
MX35_CCM_CGR1
,
16
,
NULL
,
NULL
);
DEFINE_CLOCK
(
ipu_clk
,
0
,
MX35_CCM_CGR1
,
18
,
get_rate_hsp
,
NULL
);
DEFINE_CLOCK
(
kpp_clk
,
0
,
MX35_CCM_CGR1
,
20
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
mlb_clk
,
0
,
MX35_CCM_CGR1
,
22
,
get_rate_ahb
,
NULL
);
DEFINE_CLOCK
(
mshc_clk
,
0
,
MX35_CCM_CGR1
,
24
,
get_rate_mshc
,
NULL
);
DEFINE_CLOCK
(
owire_clk
,
0
,
MX35_CCM_CGR1
,
26
,
get_rate_ipg_per
,
NULL
);
DEFINE_CLOCK
(
pwm_clk
,
0
,
MX35_CCM_CGR1
,
28
,
get_rate_ipg_per
,
NULL
);
DEFINE_CLOCK
(
rngc_clk
,
0
,
MX35_CCM_CGR1
,
30
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
rtc_clk
,
0
,
MX35_CCM_CGR2
,
0
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
rtic_clk
,
0
,
MX35_CCM_CGR2
,
2
,
get_rate_ahb
,
NULL
);
DEFINE_CLOCK
(
scc_clk
,
0
,
MX35_CCM_CGR2
,
4
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
sdma_clk
,
0
,
MX35_CCM_CGR2
,
6
,
NULL
,
NULL
);
DEFINE_CLOCK
(
spba_clk
,
0
,
MX35_CCM_CGR2
,
8
,
get_rate_ipg
,
NULL
);
DEFINE_CLOCK
(
spdif_clk
,
0
,
MX35_CCM_CGR2
,
10
,
NULL
,
NULL
);
DEFINE_CLOCK
(
ssi1_clk
,
0
,
MX35_CCM_CGR2
,
12
,
get_rate_ssi
,
NULL
);
DEFINE_CLOCK
(
ssi2_clk
,
1
,
MX35_CCM_CGR2
,
14
,
get_rate_ssi
,
NULL
);
DEFINE_CLOCK
(
uart1_clk
,
0
,
MX35_CCM_CGR2
,
16
,
get_rate_uart
,
NULL
);
DEFINE_CLOCK
(
uart2_clk
,
1
,
MX35_CCM_CGR2
,
18
,
get_rate_uart
,
NULL
);
DEFINE_CLOCK
(
uart3_clk
,
2
,
MX35_CCM_CGR2
,
20
,
get_rate_uart
,
NULL
);
DEFINE_CLOCK
(
usbotg_clk
,
0
,
MX35_CCM_CGR2
,
22
,
get_rate_otg
,
NULL
);
DEFINE_CLOCK
(
wdog_clk
,
0
,
MX35_CCM_CGR2
,
24
,
NULL
,
NULL
);
DEFINE_CLOCK
(
max_clk
,
0
,
MX35_CCM_CGR2
,
26
,
NULL
,
NULL
);
DEFINE_CLOCK
(
audmux_clk
,
0
,
MX35_CCM_CGR2
,
30
,
NULL
,
NULL
);
DEFINE_CLOCK
(
csi_clk
,
0
,
MX35_CCM_CGR3
,
0
,
get_rate_csi
,
NULL
);
DEFINE_CLOCK
(
iim_clk
,
0
,
MX35_CCM_CGR3
,
2
,
NULL
,
NULL
);
DEFINE_CLOCK
(
gpu2d_clk
,
0
,
MX35_CCM_CGR3
,
4
,
NULL
,
NULL
);
DEFINE_CLOCK
(
usbahb_clk
,
0
,
0
,
0
,
get_rate_ahb
,
NULL
);
static
int
clk_dummy_enable
(
struct
clk
*
clk
)
{
return
0
;
}
static
void
clk_dummy_disable
(
struct
clk
*
clk
)
{
}
static
unsigned
long
get_rate_nfc
(
struct
clk
*
clk
)
{
unsigned
long
div1
;
div1
=
(
__raw_readl
(
MX35_CCM_PDR4
)
>>
28
)
+
1
;
return
get_rate_ahb
(
NULL
)
/
div1
;
}
/* NAND Controller: It seems it can't be disabled */
static
struct
clk
nfc_clk
=
{
.
id
=
0
,
.
enable_reg
=
0
,
.
enable_shift
=
0
,
.
get_rate
=
get_rate_nfc
,
.
set_rate
=
NULL
,
/* set_rate_nfc, */
.
enable
=
clk_dummy_enable
,
.
disable
=
clk_dummy_disable
};
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
},
static
struct
clk_lookup
lookups
[]
=
{
_REGISTER_CLOCK
(
NULL
,
"asrc"
,
asrc_clk
)
_REGISTER_CLOCK
(
"pata_imx"
,
NULL
,
pata_clk
)
_REGISTER_CLOCK
(
"flexcan.0"
,
NULL
,
can1_clk
)
_REGISTER_CLOCK
(
"flexcan.1"
,
NULL
,
can2_clk
)
_REGISTER_CLOCK
(
"imx35-cspi.0"
,
NULL
,
cspi1_clk
)
_REGISTER_CLOCK
(
"imx35-cspi.1"
,
NULL
,
cspi2_clk
)
_REGISTER_CLOCK
(
NULL
,
"ect"
,
ect_clk
)
_REGISTER_CLOCK
(
NULL
,
"edio"
,
edio_clk
)
_REGISTER_CLOCK
(
NULL
,
"emi"
,
emi_clk
)
_REGISTER_CLOCK
(
"imx-epit.0"
,
NULL
,
epit1_clk
)
_REGISTER_CLOCK
(
"imx-epit.1"
,
NULL
,
epit2_clk
)
_REGISTER_CLOCK
(
NULL
,
"esai"
,
esai_clk
)
_REGISTER_CLOCK
(
"sdhci-esdhc-imx35.0"
,
NULL
,
esdhc1_clk
)
_REGISTER_CLOCK
(
"sdhci-esdhc-imx35.1"
,
NULL
,
esdhc2_clk
)
_REGISTER_CLOCK
(
"sdhci-esdhc-imx35.2"
,
NULL
,
esdhc3_clk
)
/* i.mx35 has the i.mx27 type fec */
_REGISTER_CLOCK
(
"imx27-fec.0"
,
NULL
,
fec_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpio"
,
gpio1_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpio"
,
gpio2_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpio"
,
gpio3_clk
)
_REGISTER_CLOCK
(
"gpt.0"
,
NULL
,
gpt_clk
)
_REGISTER_CLOCK
(
"imx-i2c.0"
,
NULL
,
i2c1_clk
)
_REGISTER_CLOCK
(
"imx-i2c.1"
,
NULL
,
i2c2_clk
)
_REGISTER_CLOCK
(
"imx-i2c.2"
,
NULL
,
i2c3_clk
)
_REGISTER_CLOCK
(
NULL
,
"iomuxc"
,
iomuxc_clk
)
_REGISTER_CLOCK
(
"ipu-core"
,
NULL
,
ipu_clk
)
_REGISTER_CLOCK
(
"mx3_sdc_fb"
,
NULL
,
ipu_clk
)
_REGISTER_CLOCK
(
NULL
,
"kpp"
,
kpp_clk
)
_REGISTER_CLOCK
(
NULL
,
"mlb"
,
mlb_clk
)
_REGISTER_CLOCK
(
NULL
,
"mshc"
,
mshc_clk
)
_REGISTER_CLOCK
(
"mxc_w1"
,
NULL
,
owire_clk
)
_REGISTER_CLOCK
(
NULL
,
"pwm"
,
pwm_clk
)
_REGISTER_CLOCK
(
NULL
,
"rngc"
,
rngc_clk
)
_REGISTER_CLOCK
(
NULL
,
"rtc"
,
rtc_clk
)
_REGISTER_CLOCK
(
NULL
,
"rtic"
,
rtic_clk
)
_REGISTER_CLOCK
(
NULL
,
"scc"
,
scc_clk
)
_REGISTER_CLOCK
(
"imx35-sdma"
,
NULL
,
sdma_clk
)
_REGISTER_CLOCK
(
NULL
,
"spba"
,
spba_clk
)
_REGISTER_CLOCK
(
NULL
,
"spdif"
,
spdif_clk
)
_REGISTER_CLOCK
(
"imx-ssi.0"
,
NULL
,
ssi1_clk
)
_REGISTER_CLOCK
(
"imx-ssi.1"
,
NULL
,
ssi2_clk
)
/* i.mx35 has the i.mx21 type uart */
_REGISTER_CLOCK
(
"imx21-uart.0"
,
NULL
,
uart1_clk
)
_REGISTER_CLOCK
(
"imx21-uart.1"
,
NULL
,
uart2_clk
)
_REGISTER_CLOCK
(
"imx21-uart.2"
,
NULL
,
uart3_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.0"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.1"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"mxc-ehci.2"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"fsl-usb2-udc"
,
"usb"
,
usbotg_clk
)
_REGISTER_CLOCK
(
"fsl-usb2-udc"
,
"usb_ahb"
,
usbahb_clk
)
_REGISTER_CLOCK
(
"imx2-wdt.0"
,
NULL
,
wdog_clk
)
_REGISTER_CLOCK
(
NULL
,
"max"
,
max_clk
)
_REGISTER_CLOCK
(
NULL
,
"audmux"
,
audmux_clk
)
_REGISTER_CLOCK
(
"mx3-camera.0"
,
NULL
,
csi_clk
)
_REGISTER_CLOCK
(
NULL
,
"iim"
,
iim_clk
)
_REGISTER_CLOCK
(
NULL
,
"gpu2d"
,
gpu2d_clk
)
_REGISTER_CLOCK
(
"mxc_nand.0"
,
NULL
,
nfc_clk
)
};
int
__init
mx35_clocks_init
()
{
unsigned
int
cgr2
=
3
<<
26
;
#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
cgr2
|=
3
<<
16
;
#endif
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
/* Turn off all clocks except the ones we need to survive, namely:
* EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
*/
__raw_writel
((
3
<<
18
),
MX35_CCM_CGR0
);
__raw_writel
((
3
<<
2
)
|
(
3
<<
4
)
|
(
3
<<
6
)
|
(
3
<<
8
)
|
(
3
<<
16
),
MX35_CCM_CGR1
);
__raw_writel
(
cgr2
,
MX35_CCM_CGR2
);
__raw_writel
(
0
,
MX35_CCM_CGR3
);
clk_enable
(
&
iim_clk
);
imx_print_silicon_rev
(
"i.MX35"
,
mx35_revision
());
clk_disable
(
&
iim_clk
);
/*
* Check if we came up in internal boot mode. If yes, we need some
* extra clocks turned on, otherwise the MX35 boot ROM code will
* hang after a watchdog reset.
*/
if
(
!
(
__raw_readl
(
MX35_CCM_RCSR
)
&
(
3
<<
10
)))
{
/* Additionally turn on UART1, SCC, and IIM clocks */
clk_enable
(
&
iim_clk
);
clk_enable
(
&
uart1_clk
);
clk_enable
(
&
scc_clk
);
}
#ifdef CONFIG_MXC_USE_EPIT
epit_timer_init
(
&
epit1_clk
,
MX35_IO_ADDRESS
(
MX35_EPIT1_BASE_ADDR
),
MX35_INT_EPIT1
);
#else
mxc_timer_init
(
&
gpt_clk
,
MX35_IO_ADDRESS
(
MX35_GPT1_BASE_ADDR
),
MX35_INT_GPT
);
#endif
return
0
;
}
arch/arm/mach-imx/clock-imx6q.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
此差异已折叠。
点击以展开。
arch/arm/mach-imx/clock-mx51-mx53.c
已删除
100644 → 0
浏览文件 @
2acd1b6f
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录