1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 The Linux Foundation. All rights reserved.
6 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10 #include <linux/reset-controller.h>
12 #include <dt-bindings/reset/qcom,sdm845-pdc.h>
14 #define RPMH_SDM845_PDC_SYNC_RESET 0x100
15 #define RPMH_SC7280_PDC_SYNC_RESET 0x1000
17 struct qcom_pdc_reset_map
{
21 struct qcom_pdc_reset_desc
{
22 const struct qcom_pdc_reset_map
*resets
;
27 struct qcom_pdc_reset_data
{
28 struct reset_controller_dev rcdev
;
29 struct regmap
*regmap
;
30 const struct qcom_pdc_reset_desc
*desc
;
33 static const struct regmap_config pdc_regmap_config
= {
38 .max_register
= 0x20000,
42 static const struct qcom_pdc_reset_map sdm845_pdc_resets
[] = {
43 [PDC_APPS_SYNC_RESET
] = {0},
44 [PDC_SP_SYNC_RESET
] = {1},
45 [PDC_AUDIO_SYNC_RESET
] = {2},
46 [PDC_SENSORS_SYNC_RESET
] = {3},
47 [PDC_AOP_SYNC_RESET
] = {4},
48 [PDC_DEBUG_SYNC_RESET
] = {5},
49 [PDC_GPU_SYNC_RESET
] = {6},
50 [PDC_DISPLAY_SYNC_RESET
] = {7},
51 [PDC_COMPUTE_SYNC_RESET
] = {8},
52 [PDC_MODEM_SYNC_RESET
] = {9},
55 static const struct qcom_pdc_reset_desc sdm845_pdc_reset_desc
= {
56 .resets
= sdm845_pdc_resets
,
57 .num_resets
= ARRAY_SIZE(sdm845_pdc_resets
),
58 .offset
= RPMH_SDM845_PDC_SYNC_RESET
,
61 static const struct qcom_pdc_reset_map sc7280_pdc_resets
[] = {
62 [PDC_APPS_SYNC_RESET
] = {0},
63 [PDC_SP_SYNC_RESET
] = {1},
64 [PDC_AUDIO_SYNC_RESET
] = {2},
65 [PDC_SENSORS_SYNC_RESET
] = {3},
66 [PDC_AOP_SYNC_RESET
] = {4},
67 [PDC_DEBUG_SYNC_RESET
] = {5},
68 [PDC_GPU_SYNC_RESET
] = {6},
69 [PDC_DISPLAY_SYNC_RESET
] = {7},
70 [PDC_COMPUTE_SYNC_RESET
] = {8},
71 [PDC_MODEM_SYNC_RESET
] = {9},
72 [PDC_WLAN_RF_SYNC_RESET
] = {10},
73 [PDC_WPSS_SYNC_RESET
] = {11},
76 static const struct qcom_pdc_reset_desc sc7280_pdc_reset_desc
= {
77 .resets
= sc7280_pdc_resets
,
78 .num_resets
= ARRAY_SIZE(sc7280_pdc_resets
),
79 .offset
= RPMH_SC7280_PDC_SYNC_RESET
,
82 static inline struct qcom_pdc_reset_data
*to_qcom_pdc_reset_data(
83 struct reset_controller_dev
*rcdev
)
85 return container_of(rcdev
, struct qcom_pdc_reset_data
, rcdev
);
88 static int qcom_pdc_control_assert(struct reset_controller_dev
*rcdev
,
91 struct qcom_pdc_reset_data
*data
= to_qcom_pdc_reset_data(rcdev
);
92 u32 mask
= BIT(data
->desc
->resets
[idx
].bit
);
94 return regmap_update_bits(data
->regmap
, data
->desc
->offset
, mask
, mask
);
97 static int qcom_pdc_control_deassert(struct reset_controller_dev
*rcdev
,
100 struct qcom_pdc_reset_data
*data
= to_qcom_pdc_reset_data(rcdev
);
101 u32 mask
= BIT(data
->desc
->resets
[idx
].bit
);
103 return regmap_update_bits(data
->regmap
, data
->desc
->offset
, mask
, 0);
106 static const struct reset_control_ops qcom_pdc_reset_ops
= {
107 .assert = qcom_pdc_control_assert
,
108 .deassert
= qcom_pdc_control_deassert
,
111 static int qcom_pdc_reset_probe(struct platform_device
*pdev
)
113 const struct qcom_pdc_reset_desc
*desc
;
114 struct qcom_pdc_reset_data
*data
;
115 struct device
*dev
= &pdev
->dev
;
118 desc
= device_get_match_data(&pdev
->dev
);
122 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
127 base
= devm_platform_ioremap_resource(pdev
, 0);
129 return PTR_ERR(base
);
131 data
->regmap
= devm_regmap_init_mmio(dev
, base
, &pdc_regmap_config
);
132 if (IS_ERR(data
->regmap
)) {
133 dev_err(dev
, "Unable to initialize regmap\n");
134 return PTR_ERR(data
->regmap
);
137 data
->rcdev
.owner
= THIS_MODULE
;
138 data
->rcdev
.ops
= &qcom_pdc_reset_ops
;
139 data
->rcdev
.nr_resets
= desc
->num_resets
;
140 data
->rcdev
.of_node
= dev
->of_node
;
142 return devm_reset_controller_register(dev
, &data
->rcdev
);
145 static const struct of_device_id qcom_pdc_reset_of_match
[] = {
146 { .compatible
= "qcom,sc7280-pdc-global", .data
= &sc7280_pdc_reset_desc
},
147 { .compatible
= "qcom,sdm845-pdc-global", .data
= &sdm845_pdc_reset_desc
},
150 MODULE_DEVICE_TABLE(of
, qcom_pdc_reset_of_match
);
152 static struct platform_driver qcom_pdc_reset_driver
= {
153 .probe
= qcom_pdc_reset_probe
,
155 .name
= "qcom_pdc_reset",
156 .of_match_table
= qcom_pdc_reset_of_match
,
159 module_platform_driver(qcom_pdc_reset_driver
);
161 MODULE_DESCRIPTION("Qualcomm PDC Reset Driver");
162 MODULE_LICENSE("GPL v2");