DRM driver code analysis: how the screen matches between uboot/uefi and kernel

Passing of parameters between uboot and kernel:

dsi_display.c
static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN];
module_param_string(dsi_display0, dsi_display_primary, MAX_CMDLINE_PARAM_LEN,	0600);
MODULE_PARM_DESC(dsi_display0,
	"msm_drm.dsi_display0=<display node>:<configX> where <display node> is 'primary dsi display node name' and <configX> where x represents index in the topology list");

MODULE_PARM_DESC: Describe the parameters

include\linux\moduleparam.h
#define module_param_string(name, string, len, perm)			\
	static const struct kparam_string __param_string_##name		\
		= {
      
       len, string };					\
	__module_param_call(MODULE_PARAM_PREFIX, name,			\
			    &param_ops_string,				\
			    .str = &__param_string_##name, perm, -1, 0);\
	__MODULE_PARM_TYPE(name, "string")

name: parameter name
string: variable name in driver code

#ifdef MODULE
#define MODULE_PARAM_PREFIX /* empty */
#else
#define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
#endif

include\linux\moduleparam.h
#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
#define __moduleparam_const
#else
#define __moduleparam_const const
#endif

vendor\qcom\opensource\display-drivers\msm\Android.mk
KBUILD_OPTIONS += MODNAME=msm_drm
注:msm_drm.dsi_display0应该就是这么来的

kernel\params.c
const struct kernel_param_ops param_ops_string = {
    
    
	.set = param_set_copystring,
	.get = param_get_string,
};

After replacing get

static const struct kparam_string __param_string_dsi_display0	= {
    
    MAX_CMDLINE_PARAM_LEN, dsi_display_primary};	\
static const char __param_str_dsi_display0[] = "msm_drm.dsi_display0";		\
static struct kernel_param const __param_dsi_display0 
						__used __section("__param")	__aligned(__alignof__(struct kernel_param))			\
	= {
    
     __param_str_dsi_display0, THIS_MODULE, &param_ops_string,			\
	    VERIFY_OCTAL_PERMISSIONS(0600), -1, 0, {
    
     .str = &__param_string_dsi_display0 } }

__param_dsi_display0 is placed in the __param segment.
Compare "msm_drm.dsi_display0" with the parameters in cmdline. If they have the same name, param_set_copystring will be called to copy the value to dsi_display_primary.

static struct dsi_display_boot_param boot_displays[MAX_DSI_ACTIVE_DISPLAY] = {
    
    
	{
    
    .boot_param = dsi_display_primary},
	{
    
    .boot_param = dsi_display_secondary},
};
vendor\qcom\opensource\display-drivers\msm\dsi\dsi_display.c
static int dsi_display_parse_boot_display_selection(void)
{
    
    
	char *pos = NULL;
	char disp_buf[MAX_CMDLINE_PARAM_LEN] = {
    
    '\0'};
	int i, j;

	for (i = 0; i < MAX_DSI_ACTIVE_DISPLAY; i++) {
    
    
		strlcpy(disp_buf, boot_displays[i].boot_param,	MAX_CMDLINE_PARAM_LEN);
		pos = strnstr(disp_buf, ":", strlen(disp_buf));
		/* Use ':' as a delimiter to retrieve the display name */
		if (!pos) {
    
    
			DSI_DEBUG("display name[%s]is not valid\n", disp_buf);
			continue;
		}
		for (j = 0; (disp_buf + j) < pos; j++)
			boot_displays[i].name[j] = *(disp_buf + j);

		boot_displays[i].name[j] = '\0';
		boot_displays[i].boot_disp_en = true;
	}
	return 0;
}

insert image description here
Image source: Xiaomi POCO F1 (xiaomi-beryllium)

The picture above shows the value of /proc/cmdline of a certain mobile phone. You can see that the screen information variable name is msm_drm.dsi_display0, and the variable value dsi_tianma_fhd_nt36672a_video_display is followed by a ':'. Corresponds to the above code.

dsi_display.c
int dsi_display_dev_probe(struct platform_device *pdev)
{
    
    
	boot_disp = &boot_displays[index];
	node = pdev->dev.of_node;
	if (boot_disp->boot_disp_en) {
    
    
		/* The panel name should be same as UEFI name index */
		panel_node = of_find_node_by_name(mdp_node, boot_disp->name);
		if (!panel_node)
			DSI_WARN("%s panel_node %s not found\n", display->display_type,
					boot_disp->name);
	} else {
    
    
		panel_node = of_parse_phandle(node,
				"qcom,dsi-default-panel", 0);
		if (!panel_node)
			DSI_WARN("%s default panel not found\n", display->display_type);
	}
}

Find a screen node in the device tree by screen name.

Q: Why not parse dts in uboot/uefi stage?
Answer: uboot/uefi will pass the first address of dtb to the kernel. There are so many parameters in dts, how to pass them to Kernel after uboot/uefi analysis?

change list:
2023.4.9 The analysis of module_param_string is more specific;

Reference materials:
[1] OnePlusoss/Android_kernel_modules_and_DeviceTree_Oneplus_SM8475
[2] Kernel: xiaomi Kernel CHANGES for Mi 10s Android R
[3] linu The role of module_parm_desc in X -drive code
[4] Drive module transmits
[5] csdn kernelr_ "Linux kernel Analysis of the cmdline parameter analysis principle"

Guess you like

Origin blog.csdn.net/yuuu_cheer/article/details/129214963