blob: 8af79a90f46a38f820bd2240ca21f7f544e45b24 [file] [log] [blame]
Bin Menge1bed0a2019-07-18 00:33:59 -07001.. SPDX-License-Identifier: GPL-2.0+
2
Simon Glass12c420c2015-11-20 10:48:47 -07003How to port a serial driver to driver model
4===========================================
5
Simon Glass90f437f2016-01-31 09:16:17 -07006Almost all of the serial drivers have been converted as at January 2016. These
7ones remain:
Simon Glass12c420c2015-11-20 10:48:47 -07008
Bin Menge1bed0a2019-07-18 00:33:59 -07009 * serial_bfin.c
10 * serial_pxa.c
Simon Glass12c420c2015-11-20 10:48:47 -070011
Simon Glass90f437f2016-01-31 09:16:17 -070012The deadline for this work was the end of January 2016. If no one steps
13forward to convert these, at some point there may come a patch to remove them!
Simon Glass12c420c2015-11-20 10:48:47 -070014
15Here is a suggested approach for converting your serial driver over to driver
16model. Please feel free to update this file with your ideas and suggestions.
17
18- #ifdef out all your own serial driver code (#ifndef CONFIG_DM_SERIAL)
19- Define CONFIG_DM_SERIAL for your board, vendor or architecture
20- If the board does not already use driver model, you need CONFIG_DM also
21- Your board should then build, but will not boot since there will be no serial
Bin Menge1bed0a2019-07-18 00:33:59 -070022 driver
Simon Glass12c420c2015-11-20 10:48:47 -070023- Add the U_BOOT_DRIVER piece at the end (e.g. copy serial_s5p.c for example)
24- Add a private struct for the driver data - avoid using static variables
25- Implement each of the driver methods, perhaps by calling your old methods
26- You may need to adjust the function parameters so that the old and new
Bin Menge1bed0a2019-07-18 00:33:59 -070027 implementations can share most of the existing code
Simon Glass12c420c2015-11-20 10:48:47 -070028- If you convert all existing users of the driver, remove the pre-driver-model
Bin Menge1bed0a2019-07-18 00:33:59 -070029 code
Simon Glass12c420c2015-11-20 10:48:47 -070030
31In terms of patches a conversion series typically has these patches:
32- clean up / prepare the driver for conversion
33- add driver model code
34- convert at least one existing board to use driver model serial
35- (if no boards remain that don't use driver model) remove the old code
36
Simon Glass85c15e42022-03-15 21:03:20 -060037This may be a good time to move your board to use the device tree too. Mostly
Simon Glass12c420c2015-11-20 10:48:47 -070038this involves these steps:
39
40- define CONFIG_OF_CONTROL and CONFIG_OF_SEPARATE
41- add your device tree files to arch/<arch>/dts
42- update the Makefile there
43- Add stdout-path to your /chosen device tree node if it is not already there
44- build and get u-boot-dtb.bin so you can test it
45- Your drivers can now use device tree
46- For device tree in SPL, define CONFIG_SPL_OF_CONTROL
Simon Glass85c15e42022-03-15 21:03:20 -060047
48
49Converting boards to CONFIG_DM_SERIAL
50-------------------------------------
51
52If your SoC has a serial driver that uses driver model (has U_BOOT_DRIVER() in
53it), then you may still find that your board has not been converted. To convert
54your board, enable the option and see if you can get it working.
55
56Firstly you will have a lot more success if you have a method of debugging your
57board, such as a JTAG connection. Failing that the debug UART is useful,
58although since you are trying to get the UART driver running, it will interfere
59with your efforts eventually.
60
61Secondly, while the UART is a relatively simple peripheral, it may need quite a
62few pieces to be up and running before it will work, such as the correct pin
63muxing, clocks, power domains and possibly even GPIOs, if an external
64transceiver is used. Look at other boards that use the same SoC, for clues as to
65what is needed.
66
67Thirdly, when added tags, put them in a xxx-u-boot.dtsi file, where xxx is your
68board name, or SoC name. There may already be a file for your SoC which contains
69what you need. U-Boot automatically includes these files: see :ref:`dttweaks`.
70
71Here are some things you might need to consider:
72
731. The serial driver itself needs to be present before relocation, so that the
74 U-Boot banner appears. Make sure it has a u-boot,pre-reloc tag in the device
75 tree, so that the serial driver is bound when U-Boot starts.
76
77 For example, on iMX8::
78
79 lpuart3: serial@5a090000 {
80 compatible = "fsl,imx8qm-lpuart";
81 ...
82 };
83
84 put this in your xxx-u-boot.dtsi file::
85
86 &lpuart3 {
87 u-boot,dm-pre-proper;
88 };
89
902. If your serial port requires a particular pinmux configuration, you may need
91 a pinctrl driver. This needs to have a u-boot,pre-reloc tag also. Take care
92 that any subnodes have the same tag, if they are needed to make the correct
93 pinctrl available.
94
95 For example, on RK3288, the UART2 uses uart2_xfer::
96
97 uart2: serial@ff690000 {
98 ...
99 pinctrl-0 = <&uart2_xfer>;
100 };
101
102 which is defined as follows::
103
104 pinctrl: pinctrl {
105 compatible = "rockchip,rk3228-pinctrl";
106
107 uart2: uart2 {
108 uart2_xfer: uart2-xfer {
109 rockchip,pins = <1 RK_PC2 RK_FUNC_2 &pcfg_pull_up>,
110 <1 RK_PC3 RK_FUNC_2 &pcfg_pull_none>;
111 };
112 ...
113 };
114
115 This means you must make the uart2-xfer node available as well as all its
116 parents, so put this in your xxx-u-boot.dtsi file::
117
118 &pinctrl {
119 u-boot,dm-pre-reloc;
120 };
121
122 &uart2 {
123 u-boot,dm-pre-reloc;
124 };
125
126 &uart2_xfer {
127 u-boot,dm-pre-reloc;
128 };
129
1303. The same applies to power domains. For example, if a particular power domain
131 must be enabled for the serial port to work, you need to ensure it is
132 available before relocation:
133
134 For example, on iMX8, put this in your xxx-u-boot.dtsi file::
135
136 &pd_dma {
137 u-boot,dm-pre-proper;
138 };
139
140 &pd_dma_lpuart3 {
141 u-boot,dm-pre-proper;
142 };
143
1444. The same applies to clocks, in the same way. Make sure that when your driver
145 requests a clock, typically with clk_get_by_index(), it is available.
146
147
148Generally a failure to find a required device will cause an error which you can
149catch, if you have the debug UART working. U-Boot outputs serial data to the
150debug UART until the point where the real serial driver takes over. This point
151is marked by gd->flags having the GD_FLG_SERIAL_READY flag set. This change
152happens in serial_init() in serial-uclass.c so until that point the debug UART
153is used. You can see the relevant code in putc()
154, for example::
155
156 /* if we don't have a console yet, use the debug UART */
157 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
158 printch(c);
159 return;
160 }
161 ... carries on to use the console / serial driver
162
163Note that in device_probe() the call to pinctrl_select_state() silently fails
164if the pinctrl driver fails. You can add a temporary check there if needed.
165
166Why do we have all these tags? The problem is that before relocation we don't
167want to bind all the drivers since memory is limited and the CPU may be running
168at a slow speed. So many boards will fail to boot without this optimisation, or
169may take a long time to start up (e.g. hundreds of milliseconds). The tags tell
170U-Boot which drivers to bind.
171
172The good news is that this problem is normally solved by the SoC, so that any
173boards that use it will work as normal. But in some cases there are multiple
174UARTs or multiple pinmux options, which means that each board may need to do
175some customisation.
176
177Serial in SPL
178-------------
179
180A similar process is needed in SPL, but in this case the u-boot,dm-spl or
181u-boot,dm-tpl tags are used. Add these in the same way as above, to ensure that
182the SPL device tree contains the required nodes (see spl/u-boot-spl.dtb for
183what it actually contains).
184
185Removing old code
186-----------------
187
188In some cases there may be initialisation code that is no-longer needed when
189driver model is used, such as setting up the pin muxing, or enabling a clock.
190Be sure to remove this.
191
192Example patch
193-------------
194
195See this serial_patch_ for iMX7.
196
197.. _serial_patch: https://patchwork.ozlabs.org/project/uboot/patch/20220314232406.1945308-1-festevam@gmail.com/