Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ae8d4048
Commit
ae8d4048
authored
Jun 03, 2015
by
Michael Turquette
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'clk-next-hi6220' into clk-next
Conflicts: drivers/clk/Kconfig
parents
19fbbbbc
72ea4861
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
680 additions
and
15 deletions
+680
-15
drivers/clk/Kconfig
drivers/clk/Kconfig
+1
-0
drivers/clk/Makefile
drivers/clk/Makefile
+1
-3
drivers/clk/hisilicon/Kconfig
drivers/clk/hisilicon/Kconfig
+6
-0
drivers/clk/hisilicon/Makefile
drivers/clk/hisilicon/Makefile
+2
-1
drivers/clk/hisilicon/clk-hi6220.c
drivers/clk/hisilicon/clk-hi6220.c
+284
-0
drivers/clk/hisilicon/clk.c
drivers/clk/hisilicon/clk.c
+29
-0
drivers/clk/hisilicon/clk.h
drivers/clk/hisilicon/clk.h
+28
-11
drivers/clk/hisilicon/clkdivider-hi6220.c
drivers/clk/hisilicon/clkdivider-hi6220.c
+156
-0
include/dt-bindings/clock/hi6220-clock.h
include/dt-bindings/clock/hi6220-clock.h
+173
-0
No files found.
drivers/clk/Kconfig
View file @
ae8d4048
...
@@ -168,6 +168,7 @@ config COMMON_CLK_CDCE706
...
@@ -168,6 +168,7 @@ config COMMON_CLK_CDCE706
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/qcom/Kconfig"
endmenu
endmenu
...
...
drivers/clk/Makefile
View file @
ae8d4048
...
@@ -48,9 +48,7 @@ obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
...
@@ -48,9 +48,7 @@ obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
obj-$(CONFIG_COMMON_CLK_AT91)
+=
at91/
obj-$(CONFIG_COMMON_CLK_AT91)
+=
at91/
obj-$(CONFIG_ARCH_BCM_MOBILE)
+=
bcm/
obj-$(CONFIG_ARCH_BCM_MOBILE)
+=
bcm/
obj-$(CONFIG_ARCH_BERLIN)
+=
berlin/
obj-$(CONFIG_ARCH_BERLIN)
+=
berlin/
obj-$(CONFIG_ARCH_HI3xxx)
+=
hisilicon/
obj-$(CONFIG_ARCH_HISI)
+=
hisilicon/
obj-$(CONFIG_ARCH_HIP04)
+=
hisilicon/
obj-$(CONFIG_ARCH_HIX5HD2)
+=
hisilicon/
obj-$(CONFIG_COMMON_CLK_KEYSTONE)
+=
keystone/
obj-$(CONFIG_COMMON_CLK_KEYSTONE)
+=
keystone/
obj-$(CONFIG_ARCH_MEDIATEK)
+=
mediatek/
obj-$(CONFIG_ARCH_MEDIATEK)
+=
mediatek/
ifeq
($(CONFIG_COMMON_CLK), y)
ifeq
($(CONFIG_COMMON_CLK), y)
...
...
drivers/clk/hisilicon/Kconfig
0 → 100644
View file @
ae8d4048
config COMMON_CLK_HI6220
bool "Hi6220 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
default ARCH_HISI
help
Build the Hisilicon Hi6220 clock driver based on the common clock framework.
drivers/clk/hisilicon/Makefile
View file @
ae8d4048
...
@@ -2,8 +2,9 @@
...
@@ -2,8 +2,9 @@
# Hisilicon Clock specific Makefile
# Hisilicon Clock specific Makefile
#
#
obj-y
+=
clk.o clkgate-separated.o
obj-y
+=
clk.o clkgate-separated.o
clkdivider-hi6220.o
obj-$(CONFIG_ARCH_HI3xxx)
+=
clk-hi3620.o
obj-$(CONFIG_ARCH_HI3xxx)
+=
clk-hi3620.o
obj-$(CONFIG_ARCH_HIP04)
+=
clk-hip04.o
obj-$(CONFIG_ARCH_HIP04)
+=
clk-hip04.o
obj-$(CONFIG_ARCH_HIX5HD2)
+=
clk-hix5hd2.o
obj-$(CONFIG_ARCH_HIX5HD2)
+=
clk-hix5hd2.o
obj-$(CONFIG_COMMON_CLK_HI6220)
+=
clk-hi6220.o
drivers/clk/hisilicon/clk-hi6220.c
0 → 100644
View file @
ae8d4048
This diff is collapsed.
Click to expand it.
drivers/clk/hisilicon/clk.c
View file @
ae8d4048
...
@@ -232,3 +232,32 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
...
@@ -232,3 +232,32 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
data
->
clk_data
.
clks
[
clks
[
i
].
id
]
=
clk
;
data
->
clk_data
.
clks
[
clks
[
i
].
id
]
=
clk
;
}
}
}
}
void
__init
hi6220_clk_register_divider
(
struct
hi6220_divider_clock
*
clks
,
int
nums
,
struct
hisi_clock_data
*
data
)
{
struct
clk
*
clk
;
void
__iomem
*
base
=
data
->
base
;
int
i
;
for
(
i
=
0
;
i
<
nums
;
i
++
)
{
clk
=
hi6220_register_clkdiv
(
NULL
,
clks
[
i
].
name
,
clks
[
i
].
parent_name
,
clks
[
i
].
flags
,
base
+
clks
[
i
].
offset
,
clks
[
i
].
shift
,
clks
[
i
].
width
,
clks
[
i
].
mask_bit
,
&
hisi_clk_lock
);
if
(
IS_ERR
(
clk
))
{
pr_err
(
"%s: failed to register clock %s
\n
"
,
__func__
,
clks
[
i
].
name
);
continue
;
}
if
(
clks
[
i
].
alias
)
clk_register_clkdev
(
clk
,
clks
[
i
].
alias
,
NULL
);
data
->
clk_data
.
clks
[
clks
[
i
].
id
]
=
clk
;
}
}
drivers/clk/hisilicon/clk.h
View file @
ae8d4048
...
@@ -79,6 +79,18 @@ struct hisi_divider_clock {
...
@@ -79,6 +79,18 @@ struct hisi_divider_clock {
const
char
*
alias
;
const
char
*
alias
;
};
};
struct
hi6220_divider_clock
{
unsigned
int
id
;
const
char
*
name
;
const
char
*
parent_name
;
unsigned
long
flags
;
unsigned
long
offset
;
u8
shift
;
u8
width
;
u32
mask_bit
;
const
char
*
alias
;
};
struct
hisi_gate_clock
{
struct
hisi_gate_clock
{
unsigned
int
id
;
unsigned
int
id
;
const
char
*
name
;
const
char
*
name
;
...
@@ -94,18 +106,23 @@ struct clk *hisi_register_clkgate_sep(struct device *, const char *,
...
@@ -94,18 +106,23 @@ struct clk *hisi_register_clkgate_sep(struct device *, const char *,
const
char
*
,
unsigned
long
,
const
char
*
,
unsigned
long
,
void
__iomem
*
,
u8
,
void
__iomem
*
,
u8
,
u8
,
spinlock_t
*
);
u8
,
spinlock_t
*
);
struct
clk
*
hi6220_register_clkdiv
(
struct
device
*
dev
,
const
char
*
name
,
const
char
*
parent_name
,
unsigned
long
flags
,
void
__iomem
*
reg
,
u8
shift
,
u8
width
,
u32
mask_bit
,
spinlock_t
*
lock
);
struct
hisi_clock_data
__init
*
hisi_clk_init
(
struct
device_node
*
,
int
);
struct
hisi_clock_data
*
hisi_clk_init
(
struct
device_node
*
,
int
);
void
__init
hisi_clk_register_fixed_rate
(
struct
hisi_fixed_rate_clock
*
,
void
hisi_clk_register_fixed_rate
(
struct
hisi_fixed_rate_clock
*
,
int
,
struct
hisi_clock_data
*
);
int
,
struct
hisi_clock_data
*
);
void
__init
hisi_clk_register_fixed_factor
(
struct
hisi_fixed_factor_clock
*
,
void
hisi_clk_register_fixed_factor
(
struct
hisi_fixed_factor_clock
*
,
int
,
struct
hisi_clock_data
*
);
int
,
struct
hisi_clock_data
*
);
void
__init
hisi_clk_register_mux
(
struct
hisi_mux_clock
*
,
int
,
void
hisi_clk_register_mux
(
struct
hisi_mux_clock
*
,
int
,
struct
hisi_clock_data
*
);
struct
hisi_clock_data
*
);
void
__init
hisi_clk_register_divider
(
struct
hisi_divider_clock
*
,
void
hisi_clk_register_divider
(
struct
hisi_divider_clock
*
,
int
,
struct
hisi_clock_data
*
);
void
hisi_clk_register_gate
(
struct
hisi_gate_clock
*
,
int
,
struct
hisi_clock_data
*
);
void
hisi_clk_register_gate_sep
(
struct
hisi_gate_clock
*
,
int
,
struct
hisi_clock_data
*
);
void
hi6220_clk_register_divider
(
struct
hi6220_divider_clock
*
,
int
,
struct
hisi_clock_data
*
);
int
,
struct
hisi_clock_data
*
);
void
__init
hisi_clk_register_gate
(
struct
hisi_gate_clock
*
,
int
,
struct
hisi_clock_data
*
);
void
__init
hisi_clk_register_gate_sep
(
struct
hisi_gate_clock
*
,
int
,
struct
hisi_clock_data
*
);
#endif
/* __HISI_CLK_H */
#endif
/* __HISI_CLK_H */
drivers/clk/hisilicon/clkdivider-hi6220.c
0 → 100644
View file @
ae8d4048
/*
* Hisilicon hi6220 SoC divider clock driver
*
* Copyright (c) 2015 Hisilicon Limited.
*
* Author: Bintian Wang <bintian.wang@huawei.com>
*
* 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.
*
*/
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#define div_mask(width) ((1 << (width)) - 1)
/**
* struct hi6220_clk_divider - divider clock for hi6220
*
* @hw: handle between common and hardware-specific interfaces
* @reg: register containing divider
* @shift: shift to the divider bit field
* @width: width of the divider bit field
* @mask: mask for setting divider rate
* @table: the div table that the divider supports
* @lock: register lock
*/
struct
hi6220_clk_divider
{
struct
clk_hw
hw
;
void
__iomem
*
reg
;
u8
shift
;
u8
width
;
u32
mask
;
const
struct
clk_div_table
*
table
;
spinlock_t
*
lock
;
};
#define to_hi6220_clk_divider(_hw) \
container_of(_hw, struct hi6220_clk_divider, hw)
static
unsigned
long
hi6220_clkdiv_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
unsigned
int
val
;
struct
hi6220_clk_divider
*
dclk
=
to_hi6220_clk_divider
(
hw
);
val
=
readl_relaxed
(
dclk
->
reg
)
>>
dclk
->
shift
;
val
&=
div_mask
(
dclk
->
width
);
return
divider_recalc_rate
(
hw
,
parent_rate
,
val
,
dclk
->
table
,
CLK_DIVIDER_ROUND_CLOSEST
);
}
static
long
hi6220_clkdiv_round_rate
(
struct
clk_hw
*
hw
,
unsigned
long
rate
,
unsigned
long
*
prate
)
{
struct
hi6220_clk_divider
*
dclk
=
to_hi6220_clk_divider
(
hw
);
return
divider_round_rate
(
hw
,
rate
,
prate
,
dclk
->
table
,
dclk
->
width
,
CLK_DIVIDER_ROUND_CLOSEST
);
}
static
int
hi6220_clkdiv_set_rate
(
struct
clk_hw
*
hw
,
unsigned
long
rate
,
unsigned
long
parent_rate
)
{
int
value
;
unsigned
long
flags
=
0
;
u32
data
;
struct
hi6220_clk_divider
*
dclk
=
to_hi6220_clk_divider
(
hw
);
value
=
divider_get_val
(
rate
,
parent_rate
,
dclk
->
table
,
dclk
->
width
,
CLK_DIVIDER_ROUND_CLOSEST
);
if
(
dclk
->
lock
)
spin_lock_irqsave
(
dclk
->
lock
,
flags
);
data
=
readl_relaxed
(
dclk
->
reg
);
data
&=
~
(
div_mask
(
dclk
->
width
)
<<
dclk
->
shift
);
data
|=
value
<<
dclk
->
shift
;
data
|=
dclk
->
mask
;
writel_relaxed
(
data
,
dclk
->
reg
);
if
(
dclk
->
lock
)
spin_unlock_irqrestore
(
dclk
->
lock
,
flags
);
return
0
;
}
static
const
struct
clk_ops
hi6220_clkdiv_ops
=
{
.
recalc_rate
=
hi6220_clkdiv_recalc_rate
,
.
round_rate
=
hi6220_clkdiv_round_rate
,
.
set_rate
=
hi6220_clkdiv_set_rate
,
};
struct
clk
*
hi6220_register_clkdiv
(
struct
device
*
dev
,
const
char
*
name
,
const
char
*
parent_name
,
unsigned
long
flags
,
void
__iomem
*
reg
,
u8
shift
,
u8
width
,
u32
mask_bit
,
spinlock_t
*
lock
)
{
struct
hi6220_clk_divider
*
div
;
struct
clk
*
clk
;
struct
clk_init_data
init
;
struct
clk_div_table
*
table
;
u32
max_div
,
min_div
;
int
i
;
/* allocate the divider */
div
=
kzalloc
(
sizeof
(
*
div
),
GFP_KERNEL
);
if
(
!
div
)
return
ERR_PTR
(
-
ENOMEM
);
/* Init the divider table */
max_div
=
div_mask
(
width
)
+
1
;
min_div
=
1
;
table
=
kcalloc
(
max_div
+
1
,
sizeof
(
*
table
),
GFP_KERNEL
);
if
(
!
table
)
{
kfree
(
div
);
return
ERR_PTR
(
-
ENOMEM
);
}
for
(
i
=
0
;
i
<
max_div
;
i
++
)
{
table
[
i
].
div
=
min_div
+
i
;
table
[
i
].
val
=
table
[
i
].
div
-
1
;
}
init
.
name
=
name
;
init
.
ops
=
&
hi6220_clkdiv_ops
;
init
.
flags
=
flags
;
init
.
parent_names
=
parent_name
?
&
parent_name
:
NULL
;
init
.
num_parents
=
parent_name
?
1
:
0
;
/* struct hi6220_clk_divider assignments */
div
->
reg
=
reg
;
div
->
shift
=
shift
;
div
->
width
=
width
;
div
->
mask
=
mask_bit
?
BIT
(
mask_bit
)
:
0
;
div
->
lock
=
lock
;
div
->
hw
.
init
=
&
init
;
div
->
table
=
table
;
/* register the clock */
clk
=
clk_register
(
dev
,
&
div
->
hw
);
if
(
IS_ERR
(
clk
))
{
kfree
(
table
);
kfree
(
div
);
}
return
clk
;
}
include/dt-bindings/clock/hi6220-clock.h
0 → 100644
View file @
ae8d4048
/*
* Copyright (c) 2015 Hisilicon Limited.
*
* Author: Bintian Wang <bintian.wang@huawei.com>
*
* 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.
*/
#ifndef __DT_BINDINGS_CLOCK_HI6220_H
#define __DT_BINDINGS_CLOCK_HI6220_H
/* clk in Hi6220 AO (always on) controller */
#define HI6220_NONE_CLOCK 0
/* fixed rate clocks */
#define HI6220_REF32K 1
#define HI6220_CLK_TCXO 2
#define HI6220_MMC1_PAD 3
#define HI6220_MMC2_PAD 4
#define HI6220_MMC0_PAD 5
#define HI6220_PLL_BBP 6
#define HI6220_PLL_GPU 7
#define HI6220_PLL1_DDR 8
#define HI6220_PLL_SYS 9
#define HI6220_PLL_SYS_MEDIA 10
#define HI6220_DDR_SRC 11
#define HI6220_PLL_MEDIA 12
#define HI6220_PLL_DDR 13
/* fixed factor clocks */
#define HI6220_300M 14
#define HI6220_150M 15
#define HI6220_PICOPHY_SRC 16
#define HI6220_MMC0_SRC_SEL 17
#define HI6220_MMC1_SRC_SEL 18
#define HI6220_MMC2_SRC_SEL 19
#define HI6220_VPU_CODEC 20
#define HI6220_MMC0_SMP 21
#define HI6220_MMC1_SMP 22
#define HI6220_MMC2_SMP 23
/* gate clocks */
#define HI6220_WDT0_PCLK 24
#define HI6220_WDT1_PCLK 25
#define HI6220_WDT2_PCLK 26
#define HI6220_TIMER0_PCLK 27
#define HI6220_TIMER1_PCLK 28
#define HI6220_TIMER2_PCLK 29
#define HI6220_TIMER3_PCLK 30
#define HI6220_TIMER4_PCLK 31
#define HI6220_TIMER5_PCLK 32
#define HI6220_TIMER6_PCLK 33
#define HI6220_TIMER7_PCLK 34
#define HI6220_TIMER8_PCLK 35
#define HI6220_UART0_PCLK 36
#define HI6220_AO_NR_CLKS 37
/* clk in Hi6220 systrl */
/* gate clock */
#define HI6220_MMC0_CLK 1
#define HI6220_MMC0_CIUCLK 2
#define HI6220_MMC1_CLK 3
#define HI6220_MMC1_CIUCLK 4
#define HI6220_MMC2_CLK 5
#define HI6220_MMC2_CIUCLK 6
#define HI6220_USBOTG_HCLK 7
#define HI6220_CLK_PICOPHY 8
#define HI6220_HIFI 9
#define HI6220_DACODEC_PCLK 10
#define HI6220_EDMAC_ACLK 11
#define HI6220_CS_ATB 12
#define HI6220_I2C0_CLK 13
#define HI6220_I2C1_CLK 14
#define HI6220_I2C2_CLK 15
#define HI6220_I2C3_CLK 16
#define HI6220_UART1_PCLK 17
#define HI6220_UART2_PCLK 18
#define HI6220_UART3_PCLK 19
#define HI6220_UART4_PCLK 20
#define HI6220_SPI_CLK 21
#define HI6220_TSENSOR_CLK 22
#define HI6220_MMU_CLK 23
#define HI6220_HIFI_SEL 24
#define HI6220_MMC0_SYSPLL 25
#define HI6220_MMC1_SYSPLL 26
#define HI6220_MMC2_SYSPLL 27
#define HI6220_MMC0_SEL 28
#define HI6220_MMC1_SEL 29
#define HI6220_BBPPLL_SEL 30
#define HI6220_MEDIA_PLL_SRC 31
#define HI6220_MMC2_SEL 32
#define HI6220_CS_ATB_SYSPLL 33
/* mux clocks */
#define HI6220_MMC0_SRC 34
#define HI6220_MMC0_SMP_IN 35
#define HI6220_MMC1_SRC 36
#define HI6220_MMC1_SMP_IN 37
#define HI6220_MMC2_SRC 38
#define HI6220_MMC2_SMP_IN 39
#define HI6220_HIFI_SRC 40
#define HI6220_UART1_SRC 41
#define HI6220_UART2_SRC 42
#define HI6220_UART3_SRC 43
#define HI6220_UART4_SRC 44
#define HI6220_MMC0_MUX0 45
#define HI6220_MMC1_MUX0 46
#define HI6220_MMC2_MUX0 47
#define HI6220_MMC0_MUX1 48
#define HI6220_MMC1_MUX1 49
#define HI6220_MMC2_MUX1 50
/* divider clocks */
#define HI6220_CLK_BUS 51
#define HI6220_MMC0_DIV 52
#define HI6220_MMC1_DIV 53
#define HI6220_MMC2_DIV 54
#define HI6220_HIFI_DIV 55
#define HI6220_BBPPLL0_DIV 56
#define HI6220_CS_DAPB 57
#define HI6220_CS_ATB_DIV 58
#define HI6220_SYS_NR_CLKS 59
/* clk in Hi6220 media controller */
/* gate clocks */
#define HI6220_DSI_PCLK 1
#define HI6220_G3D_PCLK 2
#define HI6220_ACLK_CODEC_VPU 3
#define HI6220_ISP_SCLK 4
#define HI6220_ADE_CORE 5
#define HI6220_MED_MMU 6
#define HI6220_CFG_CSI4PHY 7
#define HI6220_CFG_CSI2PHY 8
#define HI6220_ISP_SCLK_GATE 9
#define HI6220_ISP_SCLK_GATE1 10
#define HI6220_ADE_CORE_GATE 11
#define HI6220_CODEC_VPU_GATE 12
#define HI6220_MED_SYSPLL 13
/* mux clocks */
#define HI6220_1440_1200 14
#define HI6220_1000_1200 15
#define HI6220_1000_1440 16
/* divider clocks */
#define HI6220_CODEC_JPEG 17
#define HI6220_ISP_SCLK_SRC 18
#define HI6220_ISP_SCLK1 19
#define HI6220_ADE_CORE_SRC 20
#define HI6220_ADE_PIX_SRC 21
#define HI6220_G3D_CLK 22
#define HI6220_CODEC_VPU_SRC 23
#define HI6220_MEDIA_NR_CLKS 24
/* clk in Hi6220 power controller */
/* gate clocks */
#define HI6220_PLL_GPU_GATE 1
#define HI6220_PLL1_DDR_GATE 2
#define HI6220_PLL_DDR_GATE 3
#define HI6220_PLL_MEDIA_GATE 4
#define HI6220_PLL0_BBP_GATE 5
/* divider clocks */
#define HI6220_DDRC_SRC 6
#define HI6220_DDRC_AXI1 7
#define HI6220_POWER_NR_CLKS 8
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment