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
nexedi
linux
Commits
7ae74aaf
Commit
7ae74aaf
authored
Oct 23, 2016
by
Michael Turquette
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'clk-next-oxnas' into clk-next
parents
91bbc174
d783f36f
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
231 additions
and
90 deletions
+231
-90
Documentation/devicetree/bindings/clock/oxnas,stdclk.txt
Documentation/devicetree/bindings/clock/oxnas,stdclk.txt
+6
-13
drivers/clk/clk-oxnas.c
drivers/clk/clk-oxnas.c
+155
-77
include/dt-bindings/clock/oxsemi,ox810se.h
include/dt-bindings/clock/oxsemi,ox810se.h
+30
-0
include/dt-bindings/clock/oxsemi,ox820.h
include/dt-bindings/clock/oxsemi,ox820.h
+40
-0
No files found.
Documentation/devicetree/bindings/clock/oxnas,stdclk.txt
View file @
7ae74aaf
...
...
@@ -5,22 +5,15 @@ Please also refer to clock-bindings.txt in this directory for common clock
bindings usage.
Required properties:
- compatible: Should be "oxsemi,ox810se-stdclk"
- compatible: For OX810SE, should be "oxsemi,ox810se-stdclk"
For OX820, should be "oxsemi,ox820-stdclk"
- #clock-cells: 1, see below
Parent node should have the following properties :
- compatible: Should be "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
For OX810SE, the clock indices are :
- 0: LEON
- 1: DMA_SGDMA
- 2: CIPHER
- 3: SATA
- 4: AUDIO
- 5: USBMPH
- 6: ETHA
- 7: PCIA
- 8: NAND
- compatible: For OX810SE, should be
"oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
For OX820, should be
"oxsemi,ox820-sys-ctrl", "syscon", "simple-mfd"
example:
...
...
drivers/clk/clk-oxnas.c
View file @
7ae74aaf
...
...
@@ -20,31 +20,43 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/stringify.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <dt-bindings/clock/oxsemi,ox810se.h>
#include <dt-bindings/clock/oxsemi,ox820.h>
/* Standard regmap gate clocks */
struct
clk_oxnas
{
struct
clk_oxnas
_gate
{
struct
clk_hw
hw
;
signed
char
bit
;
unsigned
int
bit
;
struct
regmap
*
regmap
;
};
struct
oxnas_stdclk_data
{
struct
clk_hw_onecell_data
*
onecell_data
;
struct
clk_oxnas_gate
**
gates
;
unsigned
int
ngates
;
struct
clk_oxnas_pll
**
plls
;
unsigned
int
nplls
;
};
/* Regmap offsets */
#define CLK_STAT_REGOFFSET 0x24
#define CLK_SET_REGOFFSET 0x2c
#define CLK_CLR_REGOFFSET 0x30
static
inline
struct
clk_oxnas
*
to_clk_oxnas
(
struct
clk_hw
*
hw
)
static
inline
struct
clk_oxnas
_gate
*
to_clk_oxnas_gate
(
struct
clk_hw
*
hw
)
{
return
container_of
(
hw
,
struct
clk_oxnas
,
hw
);
return
container_of
(
hw
,
struct
clk_oxnas
_gate
,
hw
);
}
static
int
oxnas_clk_is_enabled
(
struct
clk_hw
*
hw
)
static
int
oxnas_clk_
gate_
is_enabled
(
struct
clk_hw
*
hw
)
{
struct
clk_oxnas
*
std
=
to_clk_oxnas
(
hw
);
struct
clk_oxnas
_gate
*
std
=
to_clk_oxnas_gate
(
hw
);
int
ret
;
unsigned
int
val
;
...
...
@@ -55,29 +67,29 @@ static int oxnas_clk_is_enabled(struct clk_hw *hw)
return
val
&
BIT
(
std
->
bit
);
}
static
int
oxnas_clk_enable
(
struct
clk_hw
*
hw
)
static
int
oxnas_clk_
gate_
enable
(
struct
clk_hw
*
hw
)
{
struct
clk_oxnas
*
std
=
to_clk_oxnas
(
hw
);
struct
clk_oxnas
_gate
*
std
=
to_clk_oxnas_gate
(
hw
);
regmap_write
(
std
->
regmap
,
CLK_SET_REGOFFSET
,
BIT
(
std
->
bit
));
return
0
;
}
static
void
oxnas_clk_disable
(
struct
clk_hw
*
hw
)
static
void
oxnas_clk_
gate_
disable
(
struct
clk_hw
*
hw
)
{
struct
clk_oxnas
*
std
=
to_clk_oxnas
(
hw
);
struct
clk_oxnas
_gate
*
std
=
to_clk_oxnas_gate
(
hw
);
regmap_write
(
std
->
regmap
,
CLK_CLR_REGOFFSET
,
BIT
(
std
->
bit
));
}
static
const
struct
clk_ops
oxnas_clk_ops
=
{
.
enable
=
oxnas_clk_enable
,
.
disable
=
oxnas_clk_disable
,
.
is_enabled
=
oxnas_clk_is_enabled
,
static
const
struct
clk_ops
oxnas_clk_
gate_
ops
=
{
.
enable
=
oxnas_clk_
gate_
enable
,
.
disable
=
oxnas_clk_
gate_
disable
,
.
is_enabled
=
oxnas_clk_
gate_
is_enabled
,
};
static
const
char
*
const
o
xnas_clk
_parents
[]
=
{
static
const
char
*
const
o
sc
_parents
[]
=
{
"oscillator"
,
};
...
...
@@ -85,63 +97,138 @@ static const char *const eth_parents[] = {
"gmacclk"
,
};
#define DECLARE_STD_CLKP(__clk, __parent) \
static const struct clk_init_data clk_##__clk##_init = { \
.name = __stringify(__clk), \
.ops = &oxnas_clk_ops, \
.parent_names = __parent, \
.num_parents = ARRAY_SIZE(__parent), \
#define OXNAS_GATE(_name, _bit, _parents) \
struct clk_oxnas_gate _name = { \
.bit = (_bit), \
.hw.init = &(struct clk_init_data) { \
.name = #_name, \
.ops = &oxnas_clk_gate_ops, \
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
}, \
}
#define DECLARE_STD_CLK(__clk) DECLARE_STD_CLKP(__clk, oxnas_clk_parents)
static
OXNAS_GATE
(
ox810se_leon
,
0
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_dma_sgdma
,
1
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_cipher
,
2
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_sata
,
4
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_audio
,
5
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_usbmph
,
6
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_etha
,
7
,
eth_parents
);
static
OXNAS_GATE
(
ox810se_pciea
,
8
,
osc_parents
);
static
OXNAS_GATE
(
ox810se_nand
,
9
,
osc_parents
);
static
struct
clk_oxnas_gate
*
ox810se_gates
[]
=
{
&
ox810se_leon
,
&
ox810se_dma_sgdma
,
&
ox810se_cipher
,
&
ox810se_sata
,
&
ox810se_audio
,
&
ox810se_usbmph
,
&
ox810se_etha
,
&
ox810se_pciea
,
&
ox810se_nand
,
};
static
OXNAS_GATE
(
ox820_leon
,
0
,
osc_parents
);
static
OXNAS_GATE
(
ox820_dma_sgdma
,
1
,
osc_parents
);
static
OXNAS_GATE
(
ox820_cipher
,
2
,
osc_parents
);
static
OXNAS_GATE
(
ox820_sd
,
3
,
osc_parents
);
static
OXNAS_GATE
(
ox820_sata
,
4
,
osc_parents
);
static
OXNAS_GATE
(
ox820_audio
,
5
,
osc_parents
);
static
OXNAS_GATE
(
ox820_usbmph
,
6
,
osc_parents
);
static
OXNAS_GATE
(
ox820_etha
,
7
,
eth_parents
);
static
OXNAS_GATE
(
ox820_pciea
,
8
,
osc_parents
);
static
OXNAS_GATE
(
ox820_nand
,
9
,
osc_parents
);
static
OXNAS_GATE
(
ox820_ethb
,
10
,
eth_parents
);
static
OXNAS_GATE
(
ox820_pcieb
,
11
,
osc_parents
);
static
OXNAS_GATE
(
ox820_ref600
,
12
,
osc_parents
);
static
OXNAS_GATE
(
ox820_usbdev
,
13
,
osc_parents
);
/* Hardware Bit - Clock association */
struct
clk_oxnas_init_data
{
unsigned
long
bit
;
const
struct
clk_init_data
*
clk_init
;
static
struct
clk_oxnas_gate
*
ox820_gates
[]
=
{
&
ox820_leon
,
&
ox820_dma_sgdma
,
&
ox820_cipher
,
&
ox820_sd
,
&
ox820_sata
,
&
ox820_audio
,
&
ox820_usbmph
,
&
ox820_etha
,
&
ox820_pciea
,
&
ox820_nand
,
&
ox820_etha
,
&
ox820_pciea
,
&
ox820_ref600
,
&
ox820_usbdev
,
};
static
struct
clk_hw_onecell_data
ox810se_hw_onecell_data
=
{
.
hws
=
{
[
CLK_810_LEON
]
=
&
ox810se_leon
.
hw
,
[
CLK_810_DMA_SGDMA
]
=
&
ox810se_dma_sgdma
.
hw
,
[
CLK_810_CIPHER
]
=
&
ox810se_cipher
.
hw
,
[
CLK_810_SATA
]
=
&
ox810se_sata
.
hw
,
[
CLK_810_AUDIO
]
=
&
ox810se_audio
.
hw
,
[
CLK_810_USBMPH
]
=
&
ox810se_usbmph
.
hw
,
[
CLK_810_ETHA
]
=
&
ox810se_etha
.
hw
,
[
CLK_810_PCIEA
]
=
&
ox810se_pciea
.
hw
,
[
CLK_810_NAND
]
=
&
ox810se_nand
.
hw
,
},
.
num
=
ARRAY_SIZE
(
ox810se_gates
),
};
static
struct
clk_hw_onecell_data
ox820_hw_onecell_data
=
{
.
hws
=
{
[
CLK_820_LEON
]
=
&
ox820_leon
.
hw
,
[
CLK_820_DMA_SGDMA
]
=
&
ox820_dma_sgdma
.
hw
,
[
CLK_820_CIPHER
]
=
&
ox820_cipher
.
hw
,
[
CLK_820_SD
]
=
&
ox820_sd
.
hw
,
[
CLK_820_SATA
]
=
&
ox820_sata
.
hw
,
[
CLK_820_AUDIO
]
=
&
ox820_audio
.
hw
,
[
CLK_820_USBMPH
]
=
&
ox820_usbmph
.
hw
,
[
CLK_820_ETHA
]
=
&
ox820_etha
.
hw
,
[
CLK_820_PCIEA
]
=
&
ox820_pciea
.
hw
,
[
CLK_820_NAND
]
=
&
ox820_nand
.
hw
,
[
CLK_820_ETHB
]
=
&
ox820_ethb
.
hw
,
[
CLK_820_PCIEB
]
=
&
ox820_pcieb
.
hw
,
[
CLK_820_REF600
]
=
&
ox820_ref600
.
hw
,
[
CLK_820_USBDEV
]
=
&
ox820_usbdev
.
hw
,
},
.
num
=
ARRAY_SIZE
(
ox820_gates
),
};
/* Clk init data declaration */
DECLARE_STD_CLK
(
leon
);
DECLARE_STD_CLK
(
dma_sgdma
);
DECLARE_STD_CLK
(
cipher
);
DECLARE_STD_CLK
(
sata
);
DECLARE_STD_CLK
(
audio
);
DECLARE_STD_CLK
(
usbmph
);
DECLARE_STD_CLKP
(
etha
,
eth_parents
);
DECLARE_STD_CLK
(
pciea
);
DECLARE_STD_CLK
(
nand
);
/* Table index is clock indice */
static
const
struct
clk_oxnas_init_data
clk_oxnas_init
[]
=
{
[
0
]
=
{
0
,
&
clk_leon_init
},
[
1
]
=
{
1
,
&
clk_dma_sgdma_init
},
[
2
]
=
{
2
,
&
clk_cipher_init
},
/* Skip & Do not touch to DDR clock */
[
3
]
=
{
4
,
&
clk_sata_init
},
[
4
]
=
{
5
,
&
clk_audio_init
},
[
5
]
=
{
6
,
&
clk_usbmph_init
},
[
6
]
=
{
7
,
&
clk_etha_init
},
[
7
]
=
{
8
,
&
clk_pciea_init
},
[
8
]
=
{
9
,
&
clk_nand_init
},
static
struct
oxnas_stdclk_data
ox810se_stdclk_data
=
{
.
onecell_data
=
&
ox810se_hw_onecell_data
,
.
gates
=
ox810se_gates
,
.
ngates
=
ARRAY_SIZE
(
ox810se_gates
),
};
struct
clk_oxnas_data
{
struct
clk_oxnas
clk_oxnas
[
ARRAY_SIZE
(
clk_oxnas_init
)];
struct
clk_onecell_data
onecell_data
[
ARRAY_SIZE
(
clk_oxnas_init
)];
struct
clk
*
clks
[
ARRAY_SIZE
(
clk_oxnas_init
)];
static
struct
oxnas_stdclk_data
ox820_stdclk_data
=
{
.
onecell_data
=
&
ox820_hw_onecell_data
,
.
gates
=
ox820_gates
,
.
ngates
=
ARRAY_SIZE
(
ox820_gates
),
};
static
const
struct
of_device_id
oxnas_stdclk_dt_ids
[]
=
{
{
.
compatible
=
"oxsemi,ox810se-stdclk"
,
&
ox810se_stdclk_data
},
{
.
compatible
=
"oxsemi,ox820-stdclk"
,
&
ox820_stdclk_data
},
{
}
};
static
int
oxnas_stdclk_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
clk_oxnas_data
*
clk_oxnas
;
const
struct
oxnas_stdclk_data
*
data
;
const
struct
of_device_id
*
id
;
struct
regmap
*
regmap
;
int
ret
;
int
i
;
clk_oxnas
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
clk_oxnas
),
GFP_KERNEL
);
if
(
!
clk_oxnas
)
return
-
ENOMEM
;
id
=
of_match_device
(
oxnas_stdclk_dt_ids
,
&
pdev
->
dev
);
if
(
!
id
)
return
-
ENODEV
;
data
=
id
->
data
;
regmap
=
syscon_node_to_regmap
(
of_get_parent
(
np
));
if
(
IS_ERR
(
regmap
))
{
...
...
@@ -149,32 +236,23 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)
return
PTR_ERR
(
regmap
);
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clk_oxnas_init
);
i
++
)
{
struct
clk_oxnas
*
_clk
;
for
(
i
=
0
;
i
<
data
->
ngates
;
++
i
)
data
->
gates
[
i
]
->
regmap
=
regmap
;
_clk
=
&
clk_oxnas
->
clk_oxnas
[
i
];
_clk
->
bit
=
clk_oxnas_init
[
i
].
bit
;
_clk
->
hw
.
init
=
clk_oxnas_init
[
i
].
clk_init
;
_clk
->
regmap
=
regmap
;
for
(
i
=
0
;
i
<
data
->
onecell_data
->
num
;
i
++
)
{
if
(
!
data
->
onecell_data
->
hws
[
i
])
continue
;
clk_oxnas
->
clks
[
i
]
=
devm_clk_register
(
&
pdev
->
dev
,
&
_clk
->
hw
);
if
(
WARN_ON
(
IS_ERR
(
clk_oxnas
->
clks
[
i
]))
)
return
PTR_ERR
(
clk_oxnas
->
clks
[
i
])
;
ret
=
devm_clk_hw_register
(
&
pdev
->
dev
,
data
->
onecell_data
->
hws
[
i
]
);
if
(
ret
)
return
ret
;
}
clk_oxnas
->
onecell_data
->
clks
=
clk_oxnas
->
clks
;
clk_oxnas
->
onecell_data
->
clk_num
=
ARRAY_SIZE
(
clk_oxnas_init
);
return
of_clk_add_provider
(
np
,
of_clk_src_onecell_get
,
clk_oxnas
->
onecell_data
);
return
of_clk_add_hw_provider
(
np
,
of_clk_hw_onecell_get
,
data
->
onecell_data
);
}
static
const
struct
of_device_id
oxnas_stdclk_dt_ids
[]
=
{
{
.
compatible
=
"oxsemi,ox810se-stdclk"
},
{
}
};
static
struct
platform_driver
oxnas_stdclk_driver
=
{
.
probe
=
oxnas_stdclk_probe
,
.
driver
=
{
...
...
include/dt-bindings/clock/oxsemi,ox810se.h
0 → 100644
View file @
7ae74aaf
/*
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef DT_CLOCK_OXSEMI_OX810SE_H
#define DT_CLOCK_OXSEMI_OX810SE_H
#define CLK_810_LEON 0
#define CLK_810_DMA_SGDMA 1
#define CLK_810_CIPHER 2
#define CLK_810_SATA 3
#define CLK_810_AUDIO 4
#define CLK_810_USBMPH 5
#define CLK_810_ETHA 6
#define CLK_810_PCIEA 7
#define CLK_810_NAND 8
#endif
/* DT_CLOCK_OXSEMI_OX810SE_H */
include/dt-bindings/clock/oxsemi,ox820.h
0 → 100644
View file @
7ae74aaf
/*
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef DT_CLOCK_OXSEMI_OX820_H
#define DT_CLOCK_OXSEMI_OX820_H
/* PLLs */
#define CLK_820_PLLA 0
#define CLK_820_PLLB 1
/* Gate Clocks */
#define CLK_820_LEON 2
#define CLK_820_DMA_SGDMA 3
#define CLK_820_CIPHER 4
#define CLK_820_SD 5
#define CLK_820_SATA 6
#define CLK_820_AUDIO 7
#define CLK_820_USBMPH 8
#define CLK_820_ETHA 9
#define CLK_820_PCIEA 10
#define CLK_820_NAND 11
#define CLK_820_PCIEB 12
#define CLK_820_ETHB 13
#define CLK_820_REF600 14
#define CLK_820_USBDEV 15
#endif
/* DT_CLOCK_OXSEMI_OX820_H */
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