U-boot the DM-driven model relevant notes
to be noted that the key points:
General process-driven model DM bind-> ofdata_to_platdata (optional) -> probe
starts, alone bind operation is completed, and the device driver to complete the main tie set, and the note node: node is matched to the connecting node between the device driver. ofdata_to_platdata (optional) -> probe is done in device_probe function.
Clear the above two points, then began to expand the design process-driven model to a half under analysis U-boot, I based on the U-boot 2018.03 version
and DM-related initialization process has two main entrance functions are static int initf_dm (void) and static int initr_dm (void).
The first was in before the relocation, the call is initf_dm relation function call, the function is as follows:
initf_dm // perform a bind operation, initializing a tree structure model dm
dm_init_and_scan (true) // initializes the root node apparatus, the root node and one child node bind with u-boot, dm-pre- reloc property.
dm_init // root node bound to gd-> dm_root, initialize the root device
dm_scan_platdata // U_BOOT_DEVICE search using macros defined device driver matching, that is, bind the child node
dm_extended_scan_fdt // elsewhere (the device tree) search equipment and driver matching, then the bind
dm_scan_fdt // search tree in a device and device driver matching, then the bind
dm_scan_fdt_node // specific binding entry device, the function determines whether the device has a boot, dm-pre-reloc properties, If not, is not bound
lists_bind_fdt // search can be matched to drive the device
device_bind_with_driver_data // If the match to bind
device_bind_common // matching devices and drivers, networking and device nodes and parent node, that is, the establishment of tree structure
uclass_bind_device // the devices on the list corresponding U_CLASS
drv-> bind (dev) // bind device driver interface function
parent-> driver-> child_post_bind (dev) // driven child_post_bind parent node interface functions
uc-> driven uc_drv-> post_bind // class device belongs post_bind interface function (specifically, a device node is expanded at soc performed at this interface)
Thus, half of the relevant bind to flow dm introduced over, after the implementation initf_dm, the memory will have a deepest depth of 2 (only the root node, a depth of 1) tree structure, the root node hanging gd-> dm_root on.
The same, static int initr_dm (void) perform a similar operation, but,
Gd-> = Gd-dm_root_f> dm_root; Gd-> dm_root = NULL;
After the relocation, first gd-> dm_root value is assigned to gd-> dm_root_f; then cleared the gd-> dm_root, the next is re-executed dm_init_and_scan (false) operation,
dm_init_and_scan (false) // initialize the root device , and bind all child nodes of the root node
************ omitted, see initf_dm function processes
bind after the operation is completed, you can probe the operation of the device, and an example of what sdram initialization process, I use the board is based on the YYFISH board stm32f767igt. And sdram based fmc, and in addition sdram, at fmc also linked nand flash a 4Gbit, the device tree associated source code is as follows:
& fmc {
pinctrl-0 = <& fmc_pins>;
pinctrl-names = "default";
Status = "Okay" ;
# address-cells = <. 1>;
#-size cells = <. 1>;
/ Memory Configuration * * from SDRAM Datasheet MT48LC_4M32_B2B5-6A /
Bank1: Bank 0 @ {
ST, SDRAM-Control = / bits /. 8 <
st,sdram-timing = /bits/ 8 <TMRD_2 TXSR_8 TRAS_7 TRC_7 TWR_2
TRP_2 TRCD_2>;
/* refcount = (64msec/total_row_sdram)*freq - 20 */
st,sdram-refcount = < 1421 >;
};
bank3: stm32_nand {
reg = <0xA0000080 0x20>;
/*Nand flash configuretion from flash datasheet MT29F4G08ABADA*/
compatible = "micron,mt29f4g", "st,nand-flash";
st,nand-control = /bits/ 8 <FMC_PWAIT_DIS FMC_PWID_8 FMC_ECC_DIS
FMC_TCLR_6 FMC_TAR_6 FMC_ECCPS_512>;
st,nand-timing = /bits/ 8 <MEMSET_VALE_2 MEMWAIT_VALE_4 MEMHOLD_VALE_2
MEMHIZ_VALE_2>;
u-boot,dm-pre-reloc;
};
};
As it can be seen from the device file tree, hang the two nodes under fmc, but bank3; stm32_nand I added later, in order to increase support nand_flash, so stm32_nand is a child node of fmc. fmc is a child of the root node, a schematic diagram of a tree structure is as follows
root
\
the SOC
\
fmc
\
stm32_nand
face on the analysis initf_dm and initr_dm, we can see, these two functions just completed a child node of the tree root level to create, (specific analysis will be later) and after initialization sdram is before the redirect, which is carried out initf_dm completed. So initf_dm After execution, a tree in memory only as follows:
root
\
the SOC
\
FMC
at this time is not nand_flash the device node. nand_flash this device node bindings, I put the probe process fmc this node, the specific is done in ofdata_to_platdata this interface function. As shown below:
dev_for_each_subnode (bank_node, dev) {
/ * index Extract from DT * The Bank /
BANK_NAME = (char *) ofnode_get_name (bank_node);
IF (a strncmp ( "stm32_nand", BANK_NAME, strlen ( "stm32_nand"))!) // iysheng
{
lists_bind_fdt (dev, bank_node, NULL);
Continue;
}
}
As can be seen from the above code, when the device node I device_probe fmc , I would first call ofdata_to_platdata function interface corresponding to the driver in this interface function, will traverse the child nodes, if the name begins with stm32_nand found, then the device will be bind node operation, after executing this sentence Thereafter, there will be a subnode stm32_nand apparatus fmc tree node, the depth of the tree at this time from 2 to 3.
Fmc then calls the node corresponding to the probe drive interface function, as follows:
static int stm32_fmc_probe (struct udevice * dev)
{
****** some of the content, and related matters will be omitted sdram initialization
IF (device_has_children (dev))
{
struct * child_devp udevice;
int index = 0;
the while (device_get_child (dev, index ++, & child_devp)!) {
= device_probe RET (child_devp);
IF (RET <0)
BREAK;
}
}
}
As can be seen, stm32_fmc_probe time, tries all child nodes of node probe fmc. Because before stm32_nand node has been added, this time will go a probe stm32_nand the device.
Then briefly sdram the probe process. Function call process is as follows:
int dram_init (void)
uclass_get_device (UCLASS_RAM, 0, & dev)
uclass_find_device (ID, index, & dev)
uclass_get_device_tail (dev, RET, devp to the)
device_probe (dev)
device_probe (the dev-> parent) // recursive probe Parent node
after the parent node uclass_resolve_seq // probe, assigned to the device a seq
dev-> flags | = DM_FLAG_ACTIVATED // set the flag to the active state of the apparatus
pinctrl_select_state (dev, "default") // initialization settings and pin associated <further analysis>
the dev-> parent-> driver-> child_pre_probe (dev) // perform driving child_pre_probe parent node interface function
drv-> ofdata_to_platdata ( dev) // execute device driver interface function ofdata_to_platdata
clk_set_defaults (dev) // associated clock device disposed
drv-> probe (dev) // call the device driver interface function probe
uclass_post_probe_device (dev) // call belongs CLASS driven post_probe interface functions
so far, sdram initialization process describes what can be seen from, device_probe process, you will first call ofdata_to_platdata interface function, and then will perform the probe interface functions.
----------------
Disclaimer: This article is CSDN blogger original article "iysheng", and follow CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement. .
Original link: https: //blog.csdn.net/iysheng/article/details/79921825