Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pmdomain: thead: Instantiate GPU power sequencer via auxiliary bus

In order to support the complex power sequencing required by the TH1520
GPU, the AON power domain driver must be responsible for initiating the
corresponding sequencer driver. This functionality is specific to
platforms where the GPU power sequencing hardware is controlled by the
AON block.

Extend the AON power domain driver to check for the presence of the
"gpu-clkgen" reset in its own device tree node.

If the property is found, create and register a new auxiliary device.
This device acts as a proxy that allows the dedicated `pwrseq-thead-gpu`
auxiliary driver to bind and take control of the sequencing logic.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com>
Link: https://lore.kernel.org/r/20250623-apr_14_for_sending-v6-3-6583ce0f6c25@samsung.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Michal Wilczynski and committed by
Ulf Hansson
da3d0b77 c7ba7a92

+52
+1
drivers/pmdomain/thead/Kconfig
··· 4 4 tristate "Support TH1520 Power Domains" 5 5 depends on TH1520_AON_PROTOCOL 6 6 select REGMAP_MMIO 7 + select AUXILIARY_BUS 7 8 help 8 9 This driver enables power domain management for the T-HEAD 9 10 TH-1520 SoC. On this SoC there are number of power domains,
+51
drivers/pmdomain/thead/th1520-pm-domains.c
··· 5 5 * Author: Michal Wilczynski <m.wilczynski@samsung.com> 6 6 */ 7 7 8 + #include <linux/auxiliary_bus.h> 8 9 #include <linux/firmware/thead/thead,th1520-aon.h> 9 10 #include <linux/slab.h> 10 11 #include <linux/platform_device.h> ··· 129 128 } 130 129 } 131 130 131 + static void th1520_pd_pwrseq_unregister_adev(void *adev) 132 + { 133 + auxiliary_device_delete(adev); 134 + auxiliary_device_uninit(adev); 135 + } 136 + 137 + static int th1520_pd_pwrseq_gpu_init(struct device *dev) 138 + { 139 + struct auxiliary_device *adev; 140 + int ret; 141 + 142 + /* 143 + * Correctly check only for the property's existence in the DT node. 144 + * We don't need to get/claim the reset here; that is the job of 145 + * the auxiliary driver that we are about to spawn. 146 + */ 147 + if (device_property_match_string(dev, "reset-names", "gpu-clkgen") < 0) 148 + /* 149 + * This is not an error. It simply means the optional sequencer 150 + * is not described in the device tree. 151 + */ 152 + return 0; 153 + 154 + adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL); 155 + if (!adev) 156 + return -ENOMEM; 157 + 158 + adev->name = "pwrseq-gpu"; 159 + adev->dev.parent = dev; 160 + 161 + ret = auxiliary_device_init(adev); 162 + if (ret) 163 + return ret; 164 + 165 + ret = auxiliary_device_add(adev); 166 + if (ret) { 167 + auxiliary_device_uninit(adev); 168 + return ret; 169 + } 170 + 171 + return devm_add_action_or_reset(dev, th1520_pd_pwrseq_unregister_adev, 172 + adev); 173 + } 174 + 132 175 static int th1520_pd_probe(struct platform_device *pdev) 133 176 { 134 177 struct generic_pm_domain **domains; ··· 231 186 if (ret) 232 187 goto err_clean_genpd; 233 188 189 + ret = th1520_pd_pwrseq_gpu_init(dev); 190 + if (ret) 191 + goto err_clean_provider; 192 + 234 193 return 0; 235 194 195 + err_clean_provider: 196 + of_genpd_del_provider(dev->of_node); 236 197 err_clean_genpd: 237 198 for (i--; i >= 0; i--) 238 199 pm_genpd_remove(domains[i]);