Skip to content

Commit 297a5fe

Browse files
committed
Merge tag 'spacemit-clk-for-6.17-1' of https://github.com/spacemit-com/linux into clk-spacemit
Pull SpacemiT clk driver updates from Yixun Lan: - Mark SpacemiT pll1_d8 clk as critical - Add reset support for SpacemiT K1 SoC * tag 'spacemit-clk-for-6.17-1' of https://github.com/spacemit-com/linux: reset: spacemit: add support for SpacemiT CCU resets clk: spacemit: mark K1 pll1_d8 as critical clk: spacemit: define three reset-only CCUs clk: spacemit: set up reset auxiliary devices soc: spacemit: create a header for clock/reset registers dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
2 parents 19272b3 + c79550f commit 297a5fe

File tree

9 files changed

+766
-130
lines changed

9 files changed

+766
-130
lines changed

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

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ properties:
1919
- spacemit,k1-syscon-apbc
2020
- spacemit,k1-syscon-apmu
2121
- spacemit,k1-syscon-mpmu
22+
- spacemit,k1-syscon-rcpu
23+
- spacemit,k1-syscon-rcpu2
24+
- spacemit,k1-syscon-apbc2
2225

2326
reg:
2427
maxItems: 1
@@ -47,23 +50,35 @@ properties:
4750
required:
4851
- compatible
4952
- reg
50-
- clocks
51-
- clock-names
52-
- "#clock-cells"
5353
- "#reset-cells"
5454

5555
allOf:
5656
- if:
5757
properties:
5858
compatible:
5959
contains:
60-
const: spacemit,k1-syscon-apbc
60+
enum:
61+
- spacemit,k1-syscon-apmu
62+
- spacemit,k1-syscon-mpmu
6163
then:
64+
required:
65+
- "#power-domain-cells"
66+
else:
6267
properties:
6368
"#power-domain-cells": false
64-
else:
69+
- if:
70+
properties:
71+
compatible:
72+
contains:
73+
enum:
74+
- spacemit,k1-syscon-apbc
75+
- spacemit,k1-syscon-apmu
76+
- spacemit,k1-syscon-mpmu
77+
then:
6578
required:
66-
- "#power-domain-cells"
79+
- clocks
80+
- clock-names
81+
- "#clock-cells"
6782

6883
additionalProperties: false
6984

drivers/clk/spacemit/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
config SPACEMIT_CCU
44
tristate "Clock support for SpacemiT SoCs"
55
depends on ARCH_SPACEMIT || COMPILE_TEST
6+
select AUXILIARY_BUS
67
select MFD_SYSCON
78
help
89
Say Y to enable clock controller unit support for SpacemiT SoCs.

drivers/clk/spacemit/ccu-k1.c

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

77
#include <linux/array_size.h>
8+
#include <linux/auxiliary_bus.h>
89
#include <linux/clk-provider.h>
910
#include <linux/delay.h>
11+
#include <linux/idr.h>
1012
#include <linux/mfd/syscon.h>
1113
#include <linux/minmax.h>
1214
#include <linux/module.h>
1315
#include <linux/platform_device.h>
16+
#include <linux/slab.h>
17+
#include <soc/spacemit/k1-syscon.h>
1418

1519
#include "ccu_common.h"
1620
#include "ccu_pll.h"
@@ -19,121 +23,14 @@
1923

2024
#include <dt-bindings/clock/spacemit,k1-syscon.h>
2125

22-
/* APBS register offset */
23-
#define APBS_PLL1_SWCR1 0x100
24-
#define APBS_PLL1_SWCR2 0x104
25-
#define APBS_PLL1_SWCR3 0x108
26-
#define APBS_PLL2_SWCR1 0x118
27-
#define APBS_PLL2_SWCR2 0x11c
28-
#define APBS_PLL2_SWCR3 0x120
29-
#define APBS_PLL3_SWCR1 0x124
30-
#define APBS_PLL3_SWCR2 0x128
31-
#define APBS_PLL3_SWCR3 0x12c
32-
33-
/* MPMU register offset */
34-
#define MPMU_POSR 0x0010
35-
#define POSR_PLL1_LOCK BIT(27)
36-
#define POSR_PLL2_LOCK BIT(28)
37-
#define POSR_PLL3_LOCK BIT(29)
38-
#define MPMU_SUCCR 0x0014
39-
#define MPMU_ISCCR 0x0044
40-
#define MPMU_WDTPCR 0x0200
41-
#define MPMU_RIPCCR 0x0210
42-
#define MPMU_ACGR 0x1024
43-
#define MPMU_APBCSCR 0x1050
44-
#define MPMU_SUCCR_1 0x10b0
45-
46-
/* APBC register offset */
47-
#define APBC_UART1_CLK_RST 0x00
48-
#define APBC_UART2_CLK_RST 0x04
49-
#define APBC_GPIO_CLK_RST 0x08
50-
#define APBC_PWM0_CLK_RST 0x0c
51-
#define APBC_PWM1_CLK_RST 0x10
52-
#define APBC_PWM2_CLK_RST 0x14
53-
#define APBC_PWM3_CLK_RST 0x18
54-
#define APBC_TWSI8_CLK_RST 0x20
55-
#define APBC_UART3_CLK_RST 0x24
56-
#define APBC_RTC_CLK_RST 0x28
57-
#define APBC_TWSI0_CLK_RST 0x2c
58-
#define APBC_TWSI1_CLK_RST 0x30
59-
#define APBC_TIMERS1_CLK_RST 0x34
60-
#define APBC_TWSI2_CLK_RST 0x38
61-
#define APBC_AIB_CLK_RST 0x3c
62-
#define APBC_TWSI4_CLK_RST 0x40
63-
#define APBC_TIMERS2_CLK_RST 0x44
64-
#define APBC_ONEWIRE_CLK_RST 0x48
65-
#define APBC_TWSI5_CLK_RST 0x4c
66-
#define APBC_DRO_CLK_RST 0x58
67-
#define APBC_IR_CLK_RST 0x5c
68-
#define APBC_TWSI6_CLK_RST 0x60
69-
#define APBC_COUNTER_CLK_SEL 0x64
70-
#define APBC_TWSI7_CLK_RST 0x68
71-
#define APBC_TSEN_CLK_RST 0x6c
72-
#define APBC_UART4_CLK_RST 0x70
73-
#define APBC_UART5_CLK_RST 0x74
74-
#define APBC_UART6_CLK_RST 0x78
75-
#define APBC_SSP3_CLK_RST 0x7c
76-
#define APBC_SSPA0_CLK_RST 0x80
77-
#define APBC_SSPA1_CLK_RST 0x84
78-
#define APBC_IPC_AP2AUD_CLK_RST 0x90
79-
#define APBC_UART7_CLK_RST 0x94
80-
#define APBC_UART8_CLK_RST 0x98
81-
#define APBC_UART9_CLK_RST 0x9c
82-
#define APBC_CAN0_CLK_RST 0xa0
83-
#define APBC_PWM4_CLK_RST 0xa8
84-
#define APBC_PWM5_CLK_RST 0xac
85-
#define APBC_PWM6_CLK_RST 0xb0
86-
#define APBC_PWM7_CLK_RST 0xb4
87-
#define APBC_PWM8_CLK_RST 0xb8
88-
#define APBC_PWM9_CLK_RST 0xbc
89-
#define APBC_PWM10_CLK_RST 0xc0
90-
#define APBC_PWM11_CLK_RST 0xc4
91-
#define APBC_PWM12_CLK_RST 0xc8
92-
#define APBC_PWM13_CLK_RST 0xcc
93-
#define APBC_PWM14_CLK_RST 0xd0
94-
#define APBC_PWM15_CLK_RST 0xd4
95-
#define APBC_PWM16_CLK_RST 0xd8
96-
#define APBC_PWM17_CLK_RST 0xdc
97-
#define APBC_PWM18_CLK_RST 0xe0
98-
#define APBC_PWM19_CLK_RST 0xe4
99-
100-
/* APMU register offset */
101-
#define APMU_JPG_CLK_RES_CTRL 0x020
102-
#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x024
103-
#define APMU_ISP_CLK_RES_CTRL 0x038
104-
#define APMU_LCD_CLK_RES_CTRL1 0x044
105-
#define APMU_LCD_SPI_CLK_RES_CTRL 0x048
106-
#define APMU_LCD_CLK_RES_CTRL2 0x04c
107-
#define APMU_CCIC_CLK_RES_CTRL 0x050
108-
#define APMU_SDH0_CLK_RES_CTRL 0x054
109-
#define APMU_SDH1_CLK_RES_CTRL 0x058
110-
#define APMU_USB_CLK_RES_CTRL 0x05c
111-
#define APMU_QSPI_CLK_RES_CTRL 0x060
112-
#define APMU_DMA_CLK_RES_CTRL 0x064
113-
#define APMU_AES_CLK_RES_CTRL 0x068
114-
#define APMU_VPU_CLK_RES_CTRL 0x0a4
115-
#define APMU_GPU_CLK_RES_CTRL 0x0cc
116-
#define APMU_SDH2_CLK_RES_CTRL 0x0e0
117-
#define APMU_PMUA_MC_CTRL 0x0e8
118-
#define APMU_PMU_CC2_AP 0x100
119-
#define APMU_PMUA_EM_CLK_RES_CTRL 0x104
120-
#define APMU_AUDIO_CLK_RES_CTRL 0x14c
121-
#define APMU_HDMI_CLK_RES_CTRL 0x1b8
122-
#define APMU_CCI550_CLK_CTRL 0x300
123-
#define APMU_ACLK_CLK_CTRL 0x388
124-
#define APMU_CPU_C0_CLK_CTRL 0x38C
125-
#define APMU_CPU_C1_CLK_CTRL 0x390
126-
#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc
127-
#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4
128-
#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc
129-
#define APMU_EMAC0_CLK_RES_CTRL 0x3e4
130-
#define APMU_EMAC1_CLK_RES_CTRL 0x3ec
131-
13226
struct spacemit_ccu_data {
27+
const char *reset_name;
13328
struct clk_hw **hws;
13429
size_t num;
13530
};
13631

32+
static DEFINE_IDA(auxiliary_ids);
33+
13734
/* APBS clocks start, APBS region contains and only contains all PLL clocks */
13835

13936
/*
@@ -170,7 +67,8 @@ CCU_FACTOR_GATE_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(3), 4,
17067
CCU_FACTOR_GATE_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(4), 5, 1);
17168
CCU_FACTOR_GATE_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(5), 6, 1);
17269
CCU_FACTOR_GATE_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(6), 7, 1);
173-
CCU_FACTOR_GATE_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(7), 8, 1);
70+
CCU_FACTOR_GATE_FLAGS_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(7), 8, 1,
71+
CLK_IS_CRITICAL);
17472
CCU_FACTOR_GATE_DEFINE(pll1_d11_223p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(15), 11, 1);
17573
CCU_FACTOR_GATE_DEFINE(pll1_d13_189, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(16), 13, 1);
17674
CCU_FACTOR_GATE_DEFINE(pll1_d23_106p8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(20), 23, 1);
@@ -819,8 +717,9 @@ static struct clk_hw *k1_ccu_pll_hws[] = {
819717
};
820718

821719
static const struct spacemit_ccu_data k1_ccu_pll_data = {
822-
.hws = k1_ccu_pll_hws,
823-
.num = ARRAY_SIZE(k1_ccu_pll_hws),
720+
/* The PLL CCU implements no resets */
721+
.hws = k1_ccu_pll_hws,
722+
.num = ARRAY_SIZE(k1_ccu_pll_hws),
824723
};
825724

826725
static struct clk_hw *k1_ccu_mpmu_hws[] = {
@@ -860,8 +759,9 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = {
860759
};
861760

862761
static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
863-
.hws = k1_ccu_mpmu_hws,
864-
.num = ARRAY_SIZE(k1_ccu_mpmu_hws),
762+
.reset_name = "mpmu-reset",
763+
.hws = k1_ccu_mpmu_hws,
764+
.num = ARRAY_SIZE(k1_ccu_mpmu_hws),
865765
};
866766

867767
static struct clk_hw *k1_ccu_apbc_hws[] = {
@@ -968,8 +868,9 @@ static struct clk_hw *k1_ccu_apbc_hws[] = {
968868
};
969869

970870
static const struct spacemit_ccu_data k1_ccu_apbc_data = {
971-
.hws = k1_ccu_apbc_hws,
972-
.num = ARRAY_SIZE(k1_ccu_apbc_hws),
871+
.reset_name = "apbc-reset",
872+
.hws = k1_ccu_apbc_hws,
873+
.num = ARRAY_SIZE(k1_ccu_apbc_hws),
973874
};
974875

975876
static struct clk_hw *k1_ccu_apmu_hws[] = {
@@ -1038,8 +939,21 @@ static struct clk_hw *k1_ccu_apmu_hws[] = {
1038939
};
1039940

1040941
static const struct spacemit_ccu_data k1_ccu_apmu_data = {
1041-
.hws = k1_ccu_apmu_hws,
1042-
.num = ARRAY_SIZE(k1_ccu_apmu_hws),
942+
.reset_name = "apmu-reset",
943+
.hws = k1_ccu_apmu_hws,
944+
.num = ARRAY_SIZE(k1_ccu_apmu_hws),
945+
};
946+
947+
static const struct spacemit_ccu_data k1_ccu_rcpu_data = {
948+
.reset_name = "rcpu-reset",
949+
};
950+
951+
static const struct spacemit_ccu_data k1_ccu_rcpu2_data = {
952+
.reset_name = "rcpu2-reset",
953+
};
954+
955+
static const struct spacemit_ccu_data k1_ccu_apbc2_data = {
956+
.reset_name = "apbc2-reset",
1043957
};
1044958

1045959
static int spacemit_ccu_register(struct device *dev,
@@ -1050,6 +964,10 @@ static int spacemit_ccu_register(struct device *dev,
1050964
struct clk_hw_onecell_data *clk_data;
1051965
int i, ret;
1052966

967+
/* Nothing to do if the CCU does not implement any clocks */
968+
if (!data->hws)
969+
return 0;
970+
1053971
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
1054972
GFP_KERNEL);
1055973
if (!clk_data)
@@ -1090,9 +1008,74 @@ static int spacemit_ccu_register(struct device *dev,
10901008
return ret;
10911009
}
10921010

1011+
static void spacemit_cadev_release(struct device *dev)
1012+
{
1013+
struct auxiliary_device *adev = to_auxiliary_dev(dev);
1014+
1015+
ida_free(&auxiliary_ids, adev->id);
1016+
kfree(to_spacemit_ccu_adev(adev));
1017+
}
1018+
1019+
static void spacemit_adev_unregister(void *data)
1020+
{
1021+
struct auxiliary_device *adev = data;
1022+
1023+
auxiliary_device_delete(adev);
1024+
auxiliary_device_uninit(adev);
1025+
}
1026+
1027+
static int spacemit_ccu_reset_register(struct device *dev,
1028+
struct regmap *regmap,
1029+
const char *reset_name)
1030+
{
1031+
struct spacemit_ccu_adev *cadev;
1032+
struct auxiliary_device *adev;
1033+
int ret;
1034+
1035+
/* Nothing to do if the CCU does not implement a reset controller */
1036+
if (!reset_name)
1037+
return 0;
1038+
1039+
cadev = kzalloc(sizeof(*cadev), GFP_KERNEL);
1040+
if (!cadev)
1041+
return -ENOMEM;
1042+
1043+
cadev->regmap = regmap;
1044+
1045+
adev = &cadev->adev;
1046+
adev->name = reset_name;
1047+
adev->dev.parent = dev;
1048+
adev->dev.release = spacemit_cadev_release;
1049+
adev->dev.of_node = dev->of_node;
1050+
ret = ida_alloc(&auxiliary_ids, GFP_KERNEL);
1051+
if (ret < 0)
1052+
goto err_free_cadev;
1053+
adev->id = ret;
1054+
1055+
ret = auxiliary_device_init(adev);
1056+
if (ret)
1057+
goto err_free_aux_id;
1058+
1059+
ret = auxiliary_device_add(adev);
1060+
if (ret) {
1061+
auxiliary_device_uninit(adev);
1062+
return ret;
1063+
}
1064+
1065+
return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev);
1066+
1067+
err_free_aux_id:
1068+
ida_free(&auxiliary_ids, adev->id);
1069+
err_free_cadev:
1070+
kfree(cadev);
1071+
1072+
return ret;
1073+
}
1074+
10931075
static int k1_ccu_probe(struct platform_device *pdev)
10941076
{
10951077
struct regmap *base_regmap, *lock_regmap = NULL;
1078+
const struct spacemit_ccu_data *data;
10961079
struct device *dev = &pdev->dev;
10971080
int ret;
10981081

@@ -1121,11 +1104,16 @@ static int k1_ccu_probe(struct platform_device *pdev)
11211104
"failed to get lock regmap\n");
11221105
}
11231106

1124-
ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
1125-
of_device_get_match_data(dev));
1107+
data = of_device_get_match_data(dev);
1108+
1109+
ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data);
11261110
if (ret)
11271111
return dev_err_probe(dev, ret, "failed to register clocks\n");
11281112

1113+
ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name);
1114+
if (ret)
1115+
return dev_err_probe(dev, ret, "failed to register resets\n");
1116+
11291117
return 0;
11301118
}
11311119

@@ -1146,6 +1134,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
11461134
.compatible = "spacemit,k1-syscon-apmu",
11471135
.data = &k1_ccu_apmu_data,
11481136
},
1137+
{
1138+
.compatible = "spacemit,k1-syscon-rcpu",
1139+
.data = &k1_ccu_rcpu_data,
1140+
},
1141+
{
1142+
.compatible = "spacemit,k1-syscon-rcpu2",
1143+
.data = &k1_ccu_rcpu2_data,
1144+
},
1145+
{
1146+
.compatible = "spacemit,k1-syscon-apbc2",
1147+
.data = &k1_ccu_apbc2_data,
1148+
},
11491149
{ }
11501150
};
11511151
MODULE_DEVICE_TABLE(of, of_k1_ccu_match);

0 commit comments

Comments
 (0)