2013年9月12日 星期四

Dts Dtsi device tree setting and code

Device tree .dts parser, it's like Tinyxml

///////////////paser dts
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/of/fdt.c
void __init unflatten_device_tree(void)
{
    //of_allnodes get full Tree
    __unflatten_device_tree(initial_boot_params, &of_allnodes, early_init_dt_alloc_memory_arch);
   
    of_alias_scan(early_init_dt_alloc_memory_arch); //start parser
}

///
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/of/base.c
//function list,
void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
{
    ...
    ...
    // search each node
    // first node refer to /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/imx6dl.dtsi
    for_each_property_of_node(of_aliases, pp)
    {
        ...
        np = of_find_node_by_path(pp->value); //find path and its value
        ...
    }
    ...
    ...
}

///////////////init device
gedit /root/project_board/free_imx/myandroid/kernel_imx/init/main.c
static void __init do_initcalls(void)
{
    int level;

    for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
        do_initcall_level(level); //when level = 3 init imx6q_init_machine
}

///
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/mach-imx/mach-imx6q.c
static void __init imx6q_init_machine(void)
{
    struct device *parent;

    mxc_arch_reset_init_dt();
    parent = imx_soc_device_init();
    if (parent == NULL)
        pr_warn("failed to initialize soc device\n");

    of_platform_populate(NULL, of_default_bus_match_table, imx6q_auxdata_lookup, parent);
   
    //call of_find_compatible_node get match node
    imx6q_enet_init();
    imx_anatop_init();
    imx6_pm_init();
    imx6q_csi_mux_init();
    imx6q_mini_pcie_init();
}

///init "fsl,imx6q-anatop", "arm,pl310-cache", "fsl,imx51-src", "fsl,imx6q-gpc"
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/of/base.c
of_find_compatible_node(struct device_node *from,
                                            const char *type,
                                            const char *compatible)
{
    ...
   
    for ( ;np ;np = np->allnext)
    {
        if (type && !(np->type && (of_node_cmp(np->type, type) == 0)))
            continue;

        if (__of_device_is_compatible(np, compatible) && of_node_get(np))
            break;
    }
   
    ...
    return np;  //return match node
}

//////////////////////////////////u-boot///////////////////////////////////////
EX1:
open [IMX6DQRM.pdf]
find EIM_A17 in page. 263
EIM_A17 has mode ALT0, ALT1, ALT2, ALT5, ALT7
select ALT5 - GPIO2_IO21

///
open [IMX6DQRM.pdf]
find EIM_ADDR17 in page. 2241
[field descriptions] show pin function

///
open [matrix io bd ep2 20160125.pdf]
find EIM_A17 in page. 8
pin 50 EIM_A17 set as GPIO2_IO21

///
C code:
gedit /root/project_board/lollipop51/myandroid/bootable/bootloader/uboot-imx/arch/arm/include/asm/imx-common/iomux-v3.h
#define MUX_PAD_CTRL(x)        ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)

///
gedit /root/project_board/lollipop51/myandroid/bootable/bootloader/uboot-imx/board/freescale/mx6sabresd/mx6sabresd.c
#define EPDC_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_SPEED_MED |    \
    PAD_CTL_DSE_40ohm | PAD_CTL_HYS)

///
gedit /root/project_board/lollipop51/myandroid/bootable/bootloader/uboot-imx/board/freescale/mx6sabresd/mx6sabresd.c
find
imx_iomux_v3_setup_pad(MX6_PAD_EIM_A17__GPIO2_IO21 | MUX_PAD_CTRL(EPDC_PAD_CTRL));

///
MX6_PAD_EIM_A17__GPIO2_IO21
explain: pin EIM_A17 select function to GPIO2_IO21

///
PAD_CTL_PKE 
explain: Pull / Keep Enable Field = 1b
Pull/Keeper Enabled

///
PAD_CTL_SPEED_MED
explain: Speed Field = 10b
MEDIUM — Medium frequency (100, 150 MHz)

///
PAD_CTL_DSE_40ohm
explain: DSE = 110b
40_OHM — 25 Ohm @ 3.3V, 40 Ohm @ 1.8V

///
PAD_CTL_HYS
explain: Hysteresis = 1
schmitt trigger input

//////////////////////////linux kernel/////////////////////////////////////
EX2:
open [IMX6DQRM.pdf]
find NANDF_D3 in page. 281
NANDF_D3 has mode ALT0, ALT1, ALT5
select ALT5 - GPIO2_IO03

///
open [IMX6DQRM.pdf]
find PAD_CTL_PAD_NAND_DATA03 in page. 2579
[field descriptions] show pin function

///
open [matrix som bd ep2 20150325.pdf.pdf]
find NANDF_D3 in page. 20
pin NANDF_D3 set as GPIO2_IO03 in pin 87

///
open [matrix som bd ep2 20150325.pdf.pdf]
find 87 in page. 7
pin 87 connect to GPIO2_IO3

///
DTS Work:
/root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/Makefile
find [imx6dq-matrix_io.dtb]
Makefile assign to compile imx6dq-matrix_io.dts

///
/root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/imx6dq-matrix_io.dts
#include "imx6q.dtsi"
...
...
MX6QDL_PAD_GPIO_0__GPIO1_IO00         0x80000000 //0x80000000 default value do nothing in C code
MX6QDL_PAD_GPIO_2__GPIO1_IO02         0x80000000 //0x80000000 default value do nothing in C code
...
MX6QDL_PAD_NANDF_D3__GPIO2_IO03   0x1b098       //will set this value to pinctrl-imx.c
...

///
0x1b098 = 0001 1011 0000 1001 1000(b)
HYS = 1(b)
ENABLED — Schmitt trigger input

PUS = 10(b)
100K_OHM_PU — 100K Ohm Pull Up

PUE = 1(b)
PULL — Pull Enabled //select Pull function

PKE = 1(b)
ENABLED — Pull Enabled

SPEED = 10(b)
MEDIUM — Medium frequency (100, 150 MHz)

DSE = 011(b)
90_OHM — 50 Ohm @ 3.3V, 90 Ohm @ 1.8V

///dts setting
/root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/imx6q.dtsi
iomuxc: iomuxc@ 0x020e0000
{ compatible = "fsl,imx6q-iomuxc"; };

///C Code:
gedit /root/project_board/free_imx/myandroid/kernel_imx/init/main.c
static void __init do_initcalls(void)
{
    int level;

    for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
        do_initcall_level(level); //when level = 3 call imx6q_pinctrl_probe
}

///
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/mach-imx/mx6.h
#define MX6Q_IOMUXC_BASE_ADDR        0x020e0000 //match as iomuxc: iomuxc@ 0x020e0000

gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/imx6q-pinfunc.h
                                                                                            <mux_reg, conf_reg, input_reg, mux_mode, input_val>
#define MX6QDL_PAD_NANDF_D3__GPIO2_IO03             0x308      0x6f0       0x000       0x5                0x0

///
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx6q.c
static struct of_device_id imx6q_pinctrl_of_match[] =
{
    { .compatible = "fsl,imx6q-iomuxc", },
    { /* sentinel */ }
};

static int imx6q_pinctrl_probe(struct platform_device *pdev)
{
    return imx_pinctrl_probe(pdev, &imx6q_pinctrl_info);
}

///
/root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx.c
int imx_pinctrl_probe(struct platform_device *pdev, struct imx_pinctrl_soc_info *info)
{
...
...
ret = imx_pinctrl_probe_dt(pdev, info);
...
...
//call pinctrl_register-> pinctrl_select_state -> pinconf_apply_setting -> imx_pinconf_set
ipctl->pctl = pinctrl_register(&imx_pinctrl_desc, &pdev->dev, ipctl);
...
...
}

///
/root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx.c
static int imx_pinctrl_probe_dt(struct platform_device *pdev, struct imx_pinctrl_soc_info *info)
{
...
...
    //np->name = "iomuxc"
    for_each_child_of_node(np, child)
    {
        //child->name = "board_gpios"
        ret = imx_pinctrl_parse_functions(child, info, i++);

        if (ret)
        {
            dev_err(&pdev->dev, "failed to parse function\n");
            return ret;
        }
    }
...
...
}

///
/root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx.c
static int imx_pinctrl_parse_functions(...)
{
...
...
    for_each_child_of_node(np, child)
    {
        func->groups[i] = child->name;
        grp = &info->groups[grp_index++];
        ret = imx_pinctrl_parse_groups(child, grp, info, i++);  //work here

        if (ret)
            return ret;
    }
...
}

///
/root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx.c
static int imx_pinctrl_parse_groups(...)
{
...
...
//get from MX6QDL_PAD_NANDF_D3__GPIO2_IO03
pin_reg->mux_reg = mux_reg;                            //0x308
pin_reg->conf_reg = conf_reg;                          //0x6f0
grp->input_reg[i] = be32_to_cpu(*list++);        //0x000
grp->mux_mode[i] = be32_to_cpu(*list++);    //0x5
grp->input_val[i] = be32_to_cpu(*list++);        //0x0

//get value from /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/boot/dts/imx6dq-matrix_io.dts
grp->configs[i] = config & ~IMX_PAD_SION;      //0x1b098
...
...
}

///call from pinctrl_register
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/pinctrl/pinctrl-imx.c
static int imx_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id, unsigned long config)
{
...
...
writel(config, ipctl->base + pin_reg->conf_reg); //config = 0x1b098
...
...
}

沒有留言:

張貼留言