User:Knuxify/Draft:Qualcomm/Adding a new SoC to mainline Linux: Difference between revisions

Knuxify (talk | contribs)
Knuxify (talk | contribs)
No edit summary
Line 49: Line 49:


== Porting individual parts ==
== Porting individual parts ==
'''A note about licences and copying code:''' a good chunk of drivers can be copied from downstream with minimal modifications. In those cases, keep the original copyright at the top of the file (Copyright (c) 20xx, Qualcomm Innovation Center, Inc. etc), and add yourself below. (This seems to be how it was done for milos as well.)


=== Clock controllers ===
=== Clock controllers ===
Line 73: Line 75:
</syntaxhighlight>
</syntaxhighlight>


Copy your downstream driver to <code>driver/clk/qcom/CODENAME-gcc.c</code>.
Copy your downstream driver to <code>driver/clk/qcom/CODENAME-gcc.c</code>; also copy the dt-bindings from <code>include/dt-bindings/clock/qcom,gcc-CODENAME.h</code> to <code>include/dt-bindings/clock/qcom,CODENAME-gcc.h</code> in mainline.


Paste the initialization code from another GCC driver (<syntaxhighlight inline lang="c">static struct platform_driver gcc_smXXXX_driver</syntaxhighlight> and onwards.)
(TODO these mention dispcc, I think gcc used the same steps as well)


{{todo|There are some missing struct members, these can be ommited. IIRC one has a counterpart in mainline but I don't remember which one... revisit this, maybe?}}
* <code>linux/platform_device.h</code> needs to be added to includes
* Anywhere <code>enable_safe_config</code> is set, change ops to <code>clk_rcg2_shared_ops</code><ref>https://lore.kernel.org/all/YbJMnvg%2FIDwHNeWS@ripper/</ref>.
* Remove anything related to "clock VDDs/regulators" - notably the <code>"vdd-level.h"</code> include, <code>.clkr.vdd_data</code> members in clk data struct, regulator_data in final desc struct, and the declarations at the start. AFAICT these have no mainline equivalent.
* <code>CLK_DONT_HOLD_STATE</code> in clock flags is downstream-specific, it has no equivalent in mainline.
* Look at the probe function.
** Calls to <code>clk_lucid_evo_pll_configure</code>: note down the "&disp_cc_pllX" pointers, and place them in a struct: <syntaxhighlight lang="c">static struct clk_alpha_pll *disp_cc_CODENAME_plls[] = {
&disp_cc_pll0,
};</syntaxhighlight>
** <code>regmap_update_bits</code> calls prefaced by a comment saying "Keep clocks always enabled": note down the 0x... addresses and place them in a struct like so: <syntaxhighlight lang="c">static u32 disp_cc_CODENAME_critical_cbcrs[] = {
0xe054, /* DISP_CC_XO_CLK */
};</syntaxhighlight>
** Remaining <code>regmap_update_bits</code> calls: keep them, with the comments intact, and move them into a new function: <syntaxhighlight lang="c">static void disp_cc_CODENAME_clk_regs_configure(struct device *dev, struct regmap *regmap)
{
/* Enable clock gating for MDP clocks */
regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
}</syntaxhighlight>
** Then, add the driver_data struct:<syntaxhighlight lang="c">static struct qcom_cc_driver_data disp_cc_CODENAME_driver_data = {
.alpha_plls = disp_cc_CODENAME_plls,
.num_alpha_plls = ARRAY_SIZE(disp_cc_CODENAME_plls),
.clk_cbcrs = disp_cc_CODENAME_critical_cbcrs,
.num_clk_cbcrs = ARRAY_SIZE(disp_cc_CODENAME_critical_cbcrs),
.clk_regs_configure = disp_cc_CODENAME_clk_regs_configure,
};</syntaxhighlight>
** For the rest of the probe steps, see how other drivers do it.


=== Interconnect driver ===
=== Interconnect driver ===