Skip to content

Commit 6294bb8

Browse files
committed
Merge tag 'spacemit-clk-for-6.20-1' of https://github.com/spacemit-com/linux into clk-spacemit
Pull SpacemiT clock driver updates from Yixun Lan: - Allow SpacemiT driver to be built as module - Refactor SpacemiT driver to extract common code - Add support for SpacemiT K3 SoC clk hardware * tag 'spacemit-clk-for-6.20-1' of https://github.com/spacemit-com/linux: clk: spacemit: k3: add the clock tree clk: spacemit: k3: extract common header clk: spacemit: ccu_pll: add plla type clock clk: spacemit: ccu_mix: add inverted enable gate clock dt-bindings: soc: spacemit: k3: add clock support clk: spacemit: add platform SoC prefix to reset name clk: spacemit: extract common ccu functions reset: spacemit: fix auxiliary device id clk: spacemit: prepare common ccu header clk: spacemit: Hide common clock driver from user controller clk: spacemit: Respect Kconfig setting when building modules
2 parents 8f0b4cc + e371a77 commit 6294bb8

18 files changed

Lines changed: 2609 additions & 221 deletions

File tree

Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
$id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml#
55
$schema: http://devicetree.org/meta-schemas/core.yaml#
66

7-
title: SpacemiT K1 PLL
7+
title: SpacemiT K1/K3 PLL
88

99
maintainers:
1010
- Haylen Chu <heylenay@4d2.org>
1111

1212
properties:
1313
compatible:
14-
const: spacemit,k1-pll
14+
enum:
15+
- spacemit,k1-pll
16+
- spacemit,k3-pll
1517

1618
reg:
1719
maxItems: 1
@@ -28,7 +30,8 @@ properties:
2830
"#clock-cells":
2931
const: 1
3032
description:
31-
See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
33+
For K1 SoC, check <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
34+
For K3 SoC, check <dt-bindings/clock/spacemit,k3-clocks.h> for valid indices.
3235

3336
required:
3437
- compatible

Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml#
55
$schema: http://devicetree.org/meta-schemas/core.yaml#
66

7-
title: SpacemiT K1 SoC System Controller
7+
title: SpacemiT K1/K3 SoC System Controller
88

99
maintainers:
1010
- Haylen Chu <heylenay@4d2.org>
@@ -22,6 +22,10 @@ properties:
2222
- spacemit,k1-syscon-rcpu
2323
- spacemit,k1-syscon-rcpu2
2424
- spacemit,k1-syscon-apbc2
25+
- spacemit,k3-syscon-apbc
26+
- spacemit,k3-syscon-apmu
27+
- spacemit,k3-syscon-dciu
28+
- spacemit,k3-syscon-mpmu
2529

2630
reg:
2731
maxItems: 1
@@ -39,7 +43,8 @@ properties:
3943
"#clock-cells":
4044
const: 1
4145
description:
42-
See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
46+
For K1 SoC, check <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
47+
For K3 SoC, check <dt-bindings/clock/spacemit,k3-clocks.h> for valid indices.
4348

4449
"#power-domain-cells":
4550
const: 1
@@ -60,6 +65,8 @@ allOf:
6065
enum:
6166
- spacemit,k1-syscon-apmu
6267
- spacemit,k1-syscon-mpmu
68+
- spacemit,k3-syscon-apmu
69+
- spacemit,k3-syscon-mpmu
6370
then:
6471
required:
6572
- "#power-domain-cells"
@@ -74,6 +81,9 @@ allOf:
7481
- spacemit,k1-syscon-apbc
7582
- spacemit,k1-syscon-apmu
7683
- spacemit,k1-syscon-mpmu
84+
- spacemit,k3-syscon-apbc
85+
- spacemit,k3-syscon-apmu
86+
- spacemit,k3-syscon-mpmu
7787
then:
7888
required:
7989
- clocks

drivers/clk/spacemit/Kconfig

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22

3-
config SPACEMIT_CCU
4-
tristate "Clock support for SpacemiT SoCs"
3+
menu "Clock support for SpacemiT platforms"
54
depends on ARCH_SPACEMIT || COMPILE_TEST
5+
6+
config SPACEMIT_CCU
7+
tristate
68
select AUXILIARY_BUS
79
select MFD_SYSCON
8-
help
9-
Say Y to enable clock controller unit support for SpacemiT SoCs.
10-
11-
if SPACEMIT_CCU
1210

1311
config SPACEMIT_K1_CCU
1412
tristate "Support for SpacemiT K1 SoC"
15-
depends on ARCH_SPACEMIT || COMPILE_TEST
13+
select SPACEMIT_CCU
1614
help
1715
Support for clock controller unit in SpacemiT K1 SoC.
1816

19-
endif
17+
config SPACEMIT_K3_CCU
18+
tristate "Support for SpacemiT K3 SoC"
19+
select SPACEMIT_CCU
20+
help
21+
Support for clock controller unit in SpacemiT K3 SoC.
22+
23+
endmenu

drivers/clk/spacemit/Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3-
obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o
4-
spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o
3+
obj-$(CONFIG_SPACEMIT_CCU) += spacemit-ccu.o
4+
spacemit-ccu-y += ccu_common.o
5+
spacemit-ccu-y += ccu_pll.o
6+
spacemit-ccu-y += ccu_mix.o
7+
spacemit-ccu-y += ccu_ddn.o
8+
9+
obj-$(CONFIG_SPACEMIT_K1_CCU) += spacemit-ccu-k1.o
510
spacemit-ccu-k1-y += ccu-k1.o
11+
12+
obj-$(CONFIG_SPACEMIT_K3_CCU) += spacemit-ccu-k3.o
13+
spacemit-ccu-k3-y += ccu-k3.o

drivers/clk/spacemit/ccu-k1.c

Lines changed: 12 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,10 @@
55
*/
66

77
#include <linux/array_size.h>
8-
#include <linux/auxiliary_bus.h>
98
#include <linux/clk-provider.h>
10-
#include <linux/delay.h>
11-
#include <linux/idr.h>
12-
#include <linux/mfd/syscon.h>
139
#include <linux/minmax.h>
1410
#include <linux/module.h>
1511
#include <linux/platform_device.h>
16-
#include <linux/slab.h>
1712
#include <soc/spacemit/k1-syscon.h>
1813

1914
#include "ccu_common.h"
@@ -23,14 +18,6 @@
2318

2419
#include <dt-bindings/clock/spacemit,k1-syscon.h>
2520

26-
struct spacemit_ccu_data {
27-
const char *reset_name;
28-
struct clk_hw **hws;
29-
size_t num;
30-
};
31-
32-
static DEFINE_IDA(auxiliary_ids);
33-
3421
/* APBS clocks start, APBS region contains and only contains all PLL clocks */
3522

3623
/*
@@ -802,7 +789,7 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = {
802789
};
803790

804791
static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
805-
.reset_name = "mpmu-reset",
792+
.reset_name = "k1-mpmu-reset",
806793
.hws = k1_ccu_mpmu_hws,
807794
.num = ARRAY_SIZE(k1_ccu_mpmu_hws),
808795
};
@@ -913,7 +900,7 @@ static struct clk_hw *k1_ccu_apbc_hws[] = {
913900
};
914901

915902
static const struct spacemit_ccu_data k1_ccu_apbc_data = {
916-
.reset_name = "apbc-reset",
903+
.reset_name = "k1-apbc-reset",
917904
.hws = k1_ccu_apbc_hws,
918905
.num = ARRAY_SIZE(k1_ccu_apbc_hws),
919906
};
@@ -984,184 +971,23 @@ static struct clk_hw *k1_ccu_apmu_hws[] = {
984971
};
985972

986973
static const struct spacemit_ccu_data k1_ccu_apmu_data = {
987-
.reset_name = "apmu-reset",
974+
.reset_name = "k1-apmu-reset",
988975
.hws = k1_ccu_apmu_hws,
989976
.num = ARRAY_SIZE(k1_ccu_apmu_hws),
990977
};
991978

992979
static const struct spacemit_ccu_data k1_ccu_rcpu_data = {
993-
.reset_name = "rcpu-reset",
980+
.reset_name = "k1-rcpu-reset",
994981
};
995982

996983
static const struct spacemit_ccu_data k1_ccu_rcpu2_data = {
997-
.reset_name = "rcpu2-reset",
984+
.reset_name = "k1-rcpu2-reset",
998985
};
999986

1000987
static const struct spacemit_ccu_data k1_ccu_apbc2_data = {
1001-
.reset_name = "apbc2-reset",
988+
.reset_name = "k1-apbc2-reset",
1002989
};
1003990

1004-
static int spacemit_ccu_register(struct device *dev,
1005-
struct regmap *regmap,
1006-
struct regmap *lock_regmap,
1007-
const struct spacemit_ccu_data *data)
1008-
{
1009-
struct clk_hw_onecell_data *clk_data;
1010-
int i, ret;
1011-
1012-
/* Nothing to do if the CCU does not implement any clocks */
1013-
if (!data->hws)
1014-
return 0;
1015-
1016-
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
1017-
GFP_KERNEL);
1018-
if (!clk_data)
1019-
return -ENOMEM;
1020-
1021-
clk_data->num = data->num;
1022-
1023-
for (i = 0; i < data->num; i++) {
1024-
struct clk_hw *hw = data->hws[i];
1025-
struct ccu_common *common;
1026-
const char *name;
1027-
1028-
if (!hw) {
1029-
clk_data->hws[i] = ERR_PTR(-ENOENT);
1030-
continue;
1031-
}
1032-
1033-
name = hw->init->name;
1034-
1035-
common = hw_to_ccu_common(hw);
1036-
common->regmap = regmap;
1037-
common->lock_regmap = lock_regmap;
1038-
1039-
ret = devm_clk_hw_register(dev, hw);
1040-
if (ret) {
1041-
dev_err(dev, "Cannot register clock %d - %s\n",
1042-
i, name);
1043-
return ret;
1044-
}
1045-
1046-
clk_data->hws[i] = hw;
1047-
}
1048-
1049-
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
1050-
if (ret)
1051-
dev_err(dev, "failed to add clock hardware provider (%d)\n", ret);
1052-
1053-
return ret;
1054-
}
1055-
1056-
static void spacemit_cadev_release(struct device *dev)
1057-
{
1058-
struct auxiliary_device *adev = to_auxiliary_dev(dev);
1059-
1060-
ida_free(&auxiliary_ids, adev->id);
1061-
kfree(to_spacemit_ccu_adev(adev));
1062-
}
1063-
1064-
static void spacemit_adev_unregister(void *data)
1065-
{
1066-
struct auxiliary_device *adev = data;
1067-
1068-
auxiliary_device_delete(adev);
1069-
auxiliary_device_uninit(adev);
1070-
}
1071-
1072-
static int spacemit_ccu_reset_register(struct device *dev,
1073-
struct regmap *regmap,
1074-
const char *reset_name)
1075-
{
1076-
struct spacemit_ccu_adev *cadev;
1077-
struct auxiliary_device *adev;
1078-
int ret;
1079-
1080-
/* Nothing to do if the CCU does not implement a reset controller */
1081-
if (!reset_name)
1082-
return 0;
1083-
1084-
cadev = kzalloc(sizeof(*cadev), GFP_KERNEL);
1085-
if (!cadev)
1086-
return -ENOMEM;
1087-
1088-
cadev->regmap = regmap;
1089-
1090-
adev = &cadev->adev;
1091-
adev->name = reset_name;
1092-
adev->dev.parent = dev;
1093-
adev->dev.release = spacemit_cadev_release;
1094-
adev->dev.of_node = dev->of_node;
1095-
ret = ida_alloc(&auxiliary_ids, GFP_KERNEL);
1096-
if (ret < 0)
1097-
goto err_free_cadev;
1098-
adev->id = ret;
1099-
1100-
ret = auxiliary_device_init(adev);
1101-
if (ret)
1102-
goto err_free_aux_id;
1103-
1104-
ret = auxiliary_device_add(adev);
1105-
if (ret) {
1106-
auxiliary_device_uninit(adev);
1107-
return ret;
1108-
}
1109-
1110-
return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev);
1111-
1112-
err_free_aux_id:
1113-
ida_free(&auxiliary_ids, adev->id);
1114-
err_free_cadev:
1115-
kfree(cadev);
1116-
1117-
return ret;
1118-
}
1119-
1120-
static int k1_ccu_probe(struct platform_device *pdev)
1121-
{
1122-
struct regmap *base_regmap, *lock_regmap = NULL;
1123-
const struct spacemit_ccu_data *data;
1124-
struct device *dev = &pdev->dev;
1125-
int ret;
1126-
1127-
base_regmap = device_node_to_regmap(dev->of_node);
1128-
if (IS_ERR(base_regmap))
1129-
return dev_err_probe(dev, PTR_ERR(base_regmap),
1130-
"failed to get regmap\n");
1131-
1132-
/*
1133-
* The lock status of PLLs locate in MPMU region, while PLLs themselves
1134-
* are in APBS region. Reference to MPMU syscon is required to check PLL
1135-
* status.
1136-
*/
1137-
if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) {
1138-
struct device_node *mpmu = of_parse_phandle(dev->of_node,
1139-
"spacemit,mpmu", 0);
1140-
if (!mpmu)
1141-
return dev_err_probe(dev, -ENODEV,
1142-
"Cannot parse MPMU region\n");
1143-
1144-
lock_regmap = device_node_to_regmap(mpmu);
1145-
of_node_put(mpmu);
1146-
1147-
if (IS_ERR(lock_regmap))
1148-
return dev_err_probe(dev, PTR_ERR(lock_regmap),
1149-
"failed to get lock regmap\n");
1150-
}
1151-
1152-
data = of_device_get_match_data(dev);
1153-
1154-
ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data);
1155-
if (ret)
1156-
return dev_err_probe(dev, ret, "failed to register clocks\n");
1157-
1158-
ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name);
1159-
if (ret)
1160-
return dev_err_probe(dev, ret, "failed to register resets\n");
1161-
1162-
return 0;
1163-
}
1164-
1165991
static const struct of_device_id of_k1_ccu_match[] = {
1166992
{
1167993
.compatible = "spacemit,k1-pll",
@@ -1195,6 +1021,11 @@ static const struct of_device_id of_k1_ccu_match[] = {
11951021
};
11961022
MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
11971023

1024+
static int k1_ccu_probe(struct platform_device *pdev)
1025+
{
1026+
return spacemit_ccu_probe(pdev, "spacemit,k1-pll");
1027+
}
1028+
11981029
static struct platform_driver k1_ccu_driver = {
11991030
.driver = {
12001031
.name = "spacemit,k1-ccu",
@@ -1204,6 +1035,7 @@ static struct platform_driver k1_ccu_driver = {
12041035
};
12051036
module_platform_driver(k1_ccu_driver);
12061037

1038+
MODULE_IMPORT_NS("CLK_SPACEMIT");
12071039
MODULE_DESCRIPTION("SpacemiT K1 CCU driver");
12081040
MODULE_AUTHOR("Haylen Chu <heylenay@4d2.org>");
12091041
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)