3 Preloader & Uboot

3.1 Preloader

3.1.1Preloader结构

Preloader的主题结构在文件:“alps\mediatek\platform\mt6577\preloader\src\core\main.c”中。

void main(void)

{

//时钟、uart、mcp等初始化

bldr_pre_process();



bldr_handshake(&handler);



//这里加载DSP 3G AP的ROM。



#if CFG_LOAD_UBOOT

addr = CFG_UBOOT_MEMADDR;

//加载uboot

if (bldr_load_part(PART_UBOOT, bootdev, &addr) != 0)

goto error;

#endif



//跳转到uboot

bldr_jump(addr, BOOT_ARGUMENT_ADDR, sizeof(boot_arg_t));


}

3.1.2 PLL与Clock

PLL介绍在datasheet 1190

Pll.c中“void mt6577_pll_init(void)”

似乎PLL主要是在preloader里打开的。



//设置的PLL

void mt6577_pll_init(void)

{



}



//根据MCP的型号设置DDR相关时钟

int mt6577_pll_init2 (void)

{

if (mt6577_get_dram_type() == 2)

{



}

else if (mt6577_get_dram_type() == 3)

{



}

}



3.1.3 DDR的初始化



EMI_SETTINGS emi_settings[]里面定义了KMNJS000ZM_B205 H9TP32A4GDMCPR KMSJS000KM_B308等类型的MCP的配置参数。



在“void mt6577_set_emi (void)”里面会根据“emi_settings[]”的配置初始化MCP控制器。



3.1.4 镜像布局与加载

镜像布局参数被存放在文件:

mediatek/custom/out/mt6577preloader/cust_part.c里

static part_t platform_parts[PART_MAX_COUNT];里面记录每个镜像的长度。



在mediatek/platform/mt6577/preloader/src/core/part.c里

函数int part_init(void)里,依次累加前面所有镜像,算出当前镜像的起始位置。



3.1.5 EMMC 驱动

#define MMC_HOST_ID  0

u32 mmc_init_device(void)

{…

//emmc 零通道

ret = mmc_init(MMC_HOST_ID);



}

//分别初始化host和card

int mmc_init(int id)

{



host = &sd_host[id];

card = &sd_card[id];

err = mmc_init_host(host, id);

if (err == MMC_ERR_NONE)

err = mmc_init_card(host, card);



}

//host初始化

int mmc_init_host(struct mmc_host *host, int id)

{

memset(host, 0, sizeof(struct mmc_host));

return msdc_init(host, id);

}



/*

#define MSDC0_BASE          (IO_PHYS + 0x01220000)

#define MSDC1_BASE          (IO_PHYS + 0x01230000)

#define MSDC2_BASE          (IO_PHYS + 0x01250000)

#define MSDC3_BASE          (IO_PHYS + 0x01240000)

#define IO_PHYS             0xC0000000

对于通道0,基地址在MSDC0_BASE即为0xC1220000。其余通道基地址在0xC1230000 0xC1240000  0xC1250000,但是datasheet里只有0通道0xC1220000的信息。

*/

int msdc_init(struct mmc_host *host, int id)

{

u32 baddr[] = {MSDC0_BASE, MSDC1_BASE, MSDC2_BASE, MSDC3_BASE};

//基地址选择0通道

u32 base = baddr[id];

//0通道

host->id     = id;

//基地址

host->base   = base;

host->f_max  = MSDC_MAX_SCLK;



//以下所有对0通道的寄存器操作都是基于这基地址“base”进行的

}



3.3 uboot

Uboot代码:

Generic部分:

Uboot的generic的部分位于“bootable/bootloader/uboot/”

Mt6577相关部分相关位于:

mediatek/platform/mt6577/uboot/

mediatek/custom/out/mt6577/uboot/



uboot的config:

“alps\mediatek\custom\out\mt6577\uboot\inc\configs\ubconfigs.h”

3.3.1 uboot初始化流程

Uboot初始化主体位于“bootable/bootloader/uboot/arch/arm/lib/board.c”

void start_armboot (void)

{



//执行初始化例程数组

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)

{

if ((*init_fnc_ptr)() != 0) {

hang ();

}

}



//执行平台相关misc初始化

#if defined(CONFIG_MISC_INIT_R)

/* miscellaneous platform dependent initialisations */

misc_init_r ();

#endif

}

在“bootable/bootloader/uboot/arch/arm/lib/board.c”定义了初始化例程指针数组,其中的各项例程不同的板卡有自己不同的实现:

init_fnc_t *init_sequence[] = {

cpu_init,  /* basic cpu dependent setup */

dram_init,              /* configure available RAM banks */ /*  change the original init order */

board_init,  /* basic board dependent setup */

interrupt_init,/* set up exceptions */

env_init,  /* initialize environment */

init_baudrate,/* initialze baudrate settings */

serial_init,  /* serial communications setup */

console_init_f,/* stage 1 init of console */

display_banner,/* say that we are here */



display_dram_config,

NULL,

};

Mt6577的初始化例程的实现位于“mediatek/platform/mt6577/uboot/mt6577_board.c”:

int board_init (void)

{…

mtk_serial_init();



mt6577_pinmux_init();s



pmic6329_init();

}



3.3.2 镜像布局与分区

Uboot在“int misc_init_r (…)”里对镜像分区初始化

int misc_init_r (void)

{…

mt6577_part_init(BLK_NUM(16 * GB));



}

/**********************************************************************/

在“mediatek/custom/out/mt6577/uboot/partition.h”里对分区表定义如下:

#include <common.h>

/*该文件可能就是:

“mediatek/custom/out/mt6577/uboot/inc/mt65xx_partition.h”

*/

#include "mt65xx_partition.h"

part_t partition_layout[] = {

{PART_PRELOADER, PART_BLKS_PRELOADER, PART_FLAG_NONE,0},

{PART_DSP_DL, PART_BLKS_DSP_DL, 0, PART_FLAG_NONE},



};



3.3.3 gpio初始化

DCT工具产生的“cust_gpio_boot.h”被如下文件:

mediatek/platform/mt6577/uboot/mt6577_gpio_init.c

默认设置的定义:

u16 gpio_init_mode_data[];

u16 gpio_init_dir_data[];

u16 gpio_init_pullen_data[];





设置默认设置

void mt_gpio_set_default(void)



4 Kernel

内核源码

标准内核:

Alps/kernel

Mtk部分内核

? Alps/mediatek/source/kernel/

? Alps/mediatek/platform/mt6577/kernel

? Alps/mediatek/custom/*/kernel下面也有,如

Alps/mediatek/custom/common/kernel

Alps/mediatek/custom/mt6577/kernel



4.1 ARCH初始化

4.1.1 Board支持

在“alps/mediatek/platform/mt6577/kernel/core/core.c”定义

MACHINE_START(MT6577, "MT6577")

.boot_params    = PHYS_OFFSET + 0x00000100,

.map_io         = mt6577_map_io,

.init_irq       = mt_init_irq,

.timer          = &mt6577_timer,

.init_machine   = mt6577_init,

.fixup          = mt6577_fixup

MACHINE_END



在“alps/mediatek/platform/mt6577/kernel/core/mt6577_devs.c”注册device

__init int mt6577_board_init(void)

{



retval = platform_device_register(&mt_hid_dev);

retval = platform_device_register(&mt_device_i2c[i]);

retval = platform_device_register(&AudDrv_device);

retval = platform_device_register(&mt6577_device_fb);

retval = platform_device_register(&mtk_hdmi_dev);

retval = platform_device_register(&mt6577_TVOUT_dev);



}

在“alps/kernel/mediatek/Makefile”里引用“../../mediatek/build/kernel/Makefile”,该文件即为:“alps/mediatek/build/kernel/Makefile”里面定义了相关的mt6577的内核文件:

machine-y       := $(call lc,$(MTK_PLATFORM))

ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)

MACHINE          := mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/

machdirs         := mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/

else

MACHINE         := $(MTK_PATH_PLATFORM)/core/

machdirs        := $(MTK_PATH_PLATFORM)/core/

endif

platdirs        :=

ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)

drivers-y       += mediatek/source/kernel/

drivers-y       += mediatek/custom/out/$(FULL_PROJECT)/kernel/

drivers-y       += mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/

else

drivers-y       += $(MTK_PATH_PLATFORM)/drivers/

drivers-y       += $(MTK_PATH_SOURCE)/

drivers-y       += $(MTK_PATH_CUSTOM)/

endif



4.1.2 PLL与Clock

mt6577_clock_manager.c中“static void mt6577_clock_init(void)”“static void mt6577_pll_init(void)”

mt6577的clock定义如下

enum mt65xx_clock_id {

/* PERI_GLOBALCON_PDN0 */

MT65XX_PDN_PERI_NFI                 = 0,





/* PERI_GLOBALCON_PDN1 */

MT65XX_PDN_PERI_SEJ                 = 32,



/* MMSYS1 Clock Gating #0 */

MT65XX_PDN_MM_VBUF                  = 64,



/* MMSYS1 Clock Gating #1 */

MT65XX_PDN_MM_VRZ1                  = 96,





/*MMSYS1 Clock Gating #2 */

MT65XX_PDN_MM_SCAM                  = 128,





MT65XX_CLOCK_AUDIO_PDN, /* 32*6 = 192*/

MT65XX_AUDIO_PDN_END                = MT65XX_PDN_AUDIO_I2S,



MT65XX_CLOCK_COUNT,

};



按照32,分组,enbale某个clock时,首先找到分组,然后找到组内偏移,针对某个组进行操作。中间根据clock组编号区分出 AP AP1 MM1 MM2等不同始终组,进行特殊操作。



不同的驱动在自己初始化函数里enable自己需要clock id—实际上enable对应的clock组。



int enable_clock(enum mt65xx_clock_id id, char *mod_name)

{

unsigned long flags;

int ret = 0;

int category = id / CLK_REG_WIDTH;

int offset = id % CLK_REG_WIDTH;



if (CATEGORY_AP1(category)) {



}



if (CATEGORY_MM(category)) {



}

if (CATEGORY_AUD(category)) {



}

ret = enable_clock_internal(category, mask);



5 CpuFreq

5.1 初始化



在“static int mtk_cpufreq_init(…)”里根据处理器的版本选择调频表:



static struct mtk_cpu_freq_info mt6575_freqs_e1[] = {

OP(DVFS_F2_MT6575_E1),

OP(DVFS_F1_MT6575_E1),

};



/***************************

* MT6575 E2 DVFS Table

****************************/

static struct mtk_cpu_freq_info mt6575_freqs_e2[] = {

OP(DVFS_F4_MT6575_E2),



};

/***************************

* MT6577 E1 DVFS Table

****************************/

static struct mtk_cpu_freq_info mt6577_freqs_e1[] = {

OP(DVFS_F6_MT6577_E1),



OP(DVFS_F1_MT6577_E1),

};



/***************************

* MT6577 E1 TM DVFS Table

****************************/

static struct mtk_cpu_freq_info mt6577_freqs_e1_tm[] = {

OP(DVFS_F6_MT6577_E1_TM),



OP(DVFS_F1_MT6577_E1_TM),

};



调频操作在“static int mtk_cpufreq_target()”里完成。



5.2 基本数据结构

调频例程

static struct cpufreq_driver mtk_cpufreq_driver = {

.verify = mtk_cpufreq_verify,

.target = mtk_cpufreq_target,

.init   = mtk_cpufreq_init,

.get    = mtk_cpufreq_get,

.name   = "mtk-cpufreq",

};



5.7 调频



/**********************************

* cpufreq target callback function

***********************************/

/*************************************************

* [note]

* 1. handle frequency change request

* 2. call mtk_cpufreq_set to set target frequency

**************************************************/

static int mtk_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)

{



/******************************

* look up the target frequency

*******************************/

if (cpufreq_frequency_table_target(policy, mtk_cpu_freqs_table, target_freq, relation, &idx))

return -EINVAL;

//idx是目标调频点索引值



if (get_chip_ver() >= CHIP_6577_E1)

{…

}

else if (get_chip_ver() >= CHIP_6575_E2)

{

next = &mt6575_freqs_e2[idx];

}





// next指向目标调频点

// freqs.old是当前频点,freqs.new是目标频点

freqs.old = policy->cur;

freqs.new = next->cpufreq_mhz;

freqs.cpu = policy->cpu;



#ifndef MTK_DVFS_RANDOM_TEST

if (mtk_cpufreq_keep_max_freq(freqs.old, freqs.new))

{

if ((DRV_Reg32(HW_RESV) & (0x1 << 23)) && ((DRV_Reg32(HW_RESV) & (0x1 << 20)) == 0))

freqs.new = DVFS_F1_TM;

else

freqs.new = DVFS_F1;

}



if (freqs.new > g_limited_freq)

{

dprintk("CPU frequency has been limited to %d Mhz, request %d Mhz will be limited\n", g_limited_freq / 1000, freqs.new / 1000);

freqs.new = g_limited_freq;

}



if (freqs.new < g_limited_min_freq)

{

dprintk("cannot switch CPU frequency to %d Mhz due to voltage limitation\n", g_limited_min_freq / 1000);

freqs.new = g_limited_min_freq;

}

#endif



/************************************************

* target frequency == existing frequency, skip it

*************************************************/

if (freqs.old == freqs.new)

{

dprintk("CPU frequency from %d MHz to %d MHz (skipped) due to same frequency\n", freqs.old / 1000, freqs.new / 1000);

return 0;

}





/*调频前对所有ONLINE CPU发出通知*/

for_each_online_cpu(cpu)

{

freqs.cpu = cpu;

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

}



spin_lock_irqsave(&mtk_cpufreq_lock, flags);



/*********************************************

* update current frequency due to last change

**********************************************/

freqs.old = g_cur_freq;



/******************************

* set to the target freeuency

*******************************/

//真正的调频操作

mtk_cpufreq_set(freqs.old, freqs.new);

spin_unlock_irqrestore(&mtk_cpufreq_lock, flags);



/*调频后对所有ONLINE CPU发出通知*/



for_each_online_cpu(cpu)

{

freqs.cpu = cpu;

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

}

return 0;

}



/*****************************************

* frequency ramp up and ramp down handler

******************************************/

/***********************************************************

* [note]

* 1. frequency ramp up need to wait voltage settle

* 2. frequency ramp down do not need to wait voltage settle

************************************************************/

static void mtk_cpufreq_set(unsigned int freq_old, unsigned int freq_new)

{

if (freq_new == DVFS_F1 || freq_new == DVFS_F1_TM) /* set ARMPLL divider to 1/1 */

{



}

else if (freq_new == DVFS_F2 || freq_new == DVFS_F2_TM) /* set ARMPLL divider to 5/6 */

{

if (freq_new > freq_old)

{    //升频,先调压再调频

//调压

#ifdef MTK_BUCK_ADJUST

DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));



mb();

udelay(PMIC_SETTLE_TIME);

#endif



g_cur_freq = freq_new;

//调频

DRV_WriteReg32(TOP_CKDIV1, 0x19);

}

else

{   //降频,先调频再调压

//调频

g_cur_freq = freq_new;

DRV_WriteReg32(TOP_CKDIV1, 0x19);

mb();



//调压

#ifdef MTK_BUCK_ADJUST

DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));

#endif

}

}

else if (freq_new == DVFS_F3 || freq_new == DVFS_F3_TM) /* set ARMPLL divider to 3/4 */

{



}

else if (freq_new == DVFS_F4 || freq_new == DVFS_F4_TM) /* set ARMPLL divider to 2/3 */

{

}

else if (freq_new == DVFS_F5 || freq_new == DVFS_F5_TM) /* set ARMPLL divider to 1/2 */

{

}

else if (freq_new == DVFS_F6 || freq_new == DVFS_F6_TM) /* set ARMPLL divider to 1/4 */

{

}

else if (freq_new == DVFS_F7 || freq_new == DVFS_F7_TM) /* set ARMPLL divider to 1/6 */

{

}

}



6 IRQ



6.1 中断体系

根据arm gic规范,

0-15 SGI

16-31 PPP

32以上 SPI

6.3 外部中断

typedef struct

{

void (*eint_func[EINT_MAX_CHANNEL])(void);

unsigned int eint_auto_umask[EINT_MAX_CHANNEL];

} eint_func;

通过“void mt65xx_eint_registration(…)”注册自己的中断函数。

比如“alps\mediatek\custom\common\kernel\touchpanel\ft5206\ft5206_driver.c”通过该函数注册自己的中断处理函数:

mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_POLARITY_HIGH, tpd_eint_interrupt_handler, 1);

外部中断的入口是“static irqreturn_t mt65xx_eint_isr(int irq, void *dev_id)”,该函数会检查“eint_func”数组里的处理函数。而整个外部中断入口是由EINT_IRQ中断触发。在“alps\mediatek\platform\mt6577\kernel\core\mt6577_eint.c”将EINT_IRQ中断挂入6577的中断体系。

if (request_irq(EINT_IRQ, mt65xx_eint_isr, IRQF_TRIGGER_HIGH, "EINT", NULL)) {

printk(KERN_ERR "EINT IRQ LINE NOT AVAILABLE!!\n");

}



6.4 wakeup

static u16 sc_wake_irq[NUM_WAKE_SRC] = {

[2] = MT6577_KP_IRQ_ID,

[3] = MT6577_MSDC1_IRQ_ID,

[5] = MT6577_EINT_IRQ_ID,

[6] = MT6577_RTC_IRQ_ID,

[7] = MT6577_AP_CCIF_IRQ_ID,

[8] = MT6577_ACCDET_IRQ_ID,

};



15 Driver

15.1 LCM

修改lps/mediatek/config/common/ProjectConfig.mk”里的“CUSTOM_KERNEL_LCM”和 “CUSTOM_UBOOT_LCM”选项将影响到文件“alps/mediatek/config/out/mt6577/ProjectConfig.mk”

将上述两项CUSTOM_KERNEL_LCM=hx8369_6575  CUSTOM_UBOOT_LCM=hx8369_6575

导致

alps/mediatek/custom/common/kernel/lcm/hx8369_6575/hx8369_6575.c拷到如下两个目录

alps/mediatek/custom/out/mt6577/kernel/lcm

alps/mediatek/custom/out/mt6577/uboot/lcm

mediatek\source\kernel\drivers\video

static const DISP_DRIVER DSI_DISP_DRV

const LCM_DRIVER *disp_drv_get_lcm_driver(const char *lcm_name)

15.2 BL

mediatek\source\kernel\drivers\led\leds.c

{

if(strcmp(g_leds_data[i]->cdev.name,"lcd-backlight") == 0)

{

rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_duty);

if(rc)

{

LEDS_DEBUG("[LED]device_create_file duty fail!\n");

}



rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_div);

if(rc)

{

LEDS_DEBUG("[LED]device_create_file duty fail!\n");

}



rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_frequency);

if(rc)

{

LEDS_DEBUG("[LED]device_create_file duty fail!\n");

}



rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_pwm_register);

if(rc)

{

LEDS_DEBUG("[LED]device_create_file duty fail!\n");

}

bl_setting = &g_leds_data[i]->cust;

}

}

static DEVICE_ATTR(duty, 0664, show_duty, store_duty);

g_leds_data

[   40.450409] (0)[313:ScreenOffThread][LED]Set Backlight directly 102 at time 4294941336

[   40.451398] (0)[313:ScreenOffThread]mt65xx_leds_set_cust: set brightness, name:lcd-backlight, mode:3, level:102

[   40.452744] (0)[313:ScreenOffThread]brightness_set_pmic1[LED]PMIC#3:102

[   40.454159] (0)[313:ScreenOffThread]brightness_set_pmic3 2

brightness_set_pmic

mt65xx_leds_brightness_set

led_brightness_set

15.3 TP









alps\mediatek\custom\common\kernel\touchpanel\ft5206

alps\mediatek\custom\common\kernel\touchpanel\src









15.5 Musb









15.5.1 配置

尽管在

mediatek/config/mt6577/autoconfig/kconfig/platform

CONFIG_USB_MTK_HDRC_HCD is not set

CONFIG_USB_MTK_OTG is not set









但是在

mediatek/config/mt6577/autoconfig/kconfig/project

CONFIG_USB_MTK_HDRC_HCD=y

CONFIG_USB_MTK_OTG=y

















15.5.2 Platform device & driver









mediatek\platform\mt6577\kernel\core

struct platform_device mt_device_usb = {

.name  = "mt_usb",

.id  = -1,

.dev = {

//.platform_data          = &usb_data_mt65xx,

.dma_mask               = &usb_dmamask,

.coherent_dma_mask      = DMA_BIT_MASK(32),

//.release=musbfsh_hcd_release,

},

};

























__init int mt6577_board_init(void)

{











#if defined(CONFIG_USB_MTK_HDRC)

printk("mt_device_usb register\n");

retval = platform_device_register(&mt_device_usb);

if (retval != 0){

printk("mt_device_usb register fail\n");

return retval;

}

#endif



}

















































mediatek\source\kernel\drivers\usb20









static struct platform_driver musb_driver = {

.driver = {

.name = (char *)musb_driver_name,

.owner  = THIS_MODULE,

},

.remove  = __exit_p(musb_remove),

.shutdown  = musb_shutdown,

.probe  = musb_probe,

};

































































data_array[0]=0x00103902;

data_array[1]=0x032000B2;

data_array[2]=0xFF007003;

data_array[3]=0x00000000;

data_array[4]=0x01000303;

dsi_set_cmdq(&data_array, 5, 1);









data_array[0] 为packet head  定义为:第一个字节为 WC1,第二个字节WC0,第三个字节DT (命令类型)第四个字节为控制类型。









data_array[1],data_array[2],data_array[3],data_array[4],为初始化的相应数据。

































15.6 GPIO

















GPIO初始化在uboot里完成

















GPIO在内核的定义:

cust_gpio_usage.h

























GPIO在内核的设置

mt_set_gpio_mode









15.7 IIC

15.7.1  adapter device









alps\mediatek\platform\mt6577\kernel\core\Mt6577_devs.c









static struct platform_device mt_device_i2c[] = {

{

.name           = "mt-i2c",

.id             = 0,

.num_resources  = ARRAY_SIZE(mt_resource_i2c1),

.resource       = mt_resource_i2c1,

},



{

.name           = "mt-i2c",

.id             = 2,

.num_resources  = ARRAY_SIZE(mt_resource_i2c3),

.resource       = mt_resource_i2c3,

},

};









15.7.2 adapter driver

alps\mediatek\platform\mt6577\kernel\drivers\i2c\I2c.c

















static struct platform_driver mt_i2c_driver = {

.probe = mt_i2c_probe,

.remove = mt_i2c_remove,

#ifdef CONFIG_PM

.suspend = mt_i2c_suspend,

.resume = mt_i2c_resume,

#endif

.driver  = {

.name  = DRV_NAME,

.owner = THIS_MODULE,

},

};

















15.7.3 匹配IIC通道









i2c_register_board_info

















15.8 PMIC MT6329

alps\mediatek\platform\mt6577\kernel\drivers\power\pmic_mt6329.c









i2c_register_board_info 指出mt6329使用2通道

















15.9 emmc & sd

















C:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\core\ mt6577_devs.c









static struct platform_device mt6577_device_sd[] =

{

#if defined(CFG_DEV_MSDC0)

{

.name           = "mtk-sd",

.id             = 0,

.num_resources  = ARRAY_SIZE(mt6577_resource_sd0),

.resource       = mt6577_resource_sd0,

.dev = {

.platform_data = &msdc0_hw,

},

},

#endif

#if defined(CFG_DEV_MSDC1)

{

.name           = "mtk-sd",

.id             = 1,

.num_resources  = ARRAY_SIZE(mt6577_resource_sd1),

.resource       = mt6577_resource_sd1,

.dev = {

.platform_data = &msdc1_hw,

},

},

#endif

#if defined(CFG_DEV_MSDC2)

{

.name           = "mtk-sd",

.id             = 2,

.num_resources  = ARRAY_SIZE(mt6577_resource_sd2),

.resource       = mt6577_resource_sd2,

.dev = {

.platform_data = &msdc2_hw,

},

},

#endif

#if defined(CFG_DEV_MSDC3)

{

.name           = "mtk-sd",

.id             = 3,

.num_resources  = ARRAY_SIZE(mt6577_resource_sd3),

.resource       = mt6577_resource_sd3,

.dev = {

.platform_data = &msdc3_hw,

},

},

#endif

};

















驱动

c:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\drivers\mmc-host\sd.c

















EMMC数据线定义

struct msdc_hw msdc0_hw = {

.clk_src        = 1,

.cmd_edge       = MSDC_SMPL_FALLING,

.data_edge      = MSDC_SMPL_FALLING,



.data_pins      = 8,

.data_offset    = 0,

#ifdef MTK_EMMC_SUPPORT

.flags          = MSDC_SYS_SUSPEND | MSDC_HIGHSPEED,

#else

.flags          = MSDC_SDCARD_FLAG,

#endif

};

























static struct mmc_host_ops mt_msdc_ops = {

.request         = msdc_ops_request,

.set_ios         = msdc_ops_set_ios,

.get_ro          = msdc_ops_get_ro,

.get_cd          = msdc_ops_get_cd,

.enable_sdio_irq = msdc_ops_enable_sdio_irq,

.start_signal_voltage_switch = msdc_ops_switch_volt,

};

















Host

Mmc card device

Mmc card driver









mmc_rescan 扫描mmc 家里mmc设备









mmc_init_card

















mmc_blk_probe

?add_disk

mt6577驱动开发 笔记版相关推荐

  1. 嵌入式底层驱动开发笔记1

    一.开发板 1\ bootloader的工作原理及作用? Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段 bootloader程序.这段bootload ...

  2. Linux nor flash分区,Linux驱动开发笔记:NOR FLASH编写实例

    1. 背景介绍 板子上的zynq通过emc外接一块nor flash,地址分配如下: Nor flash的起始地址为0x80000000.当zynq上运行Linux后可以通过对该地址起始的区域进行擦除 ...

  3. 设备文件BSP及嵌入式驱动开发笔记

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! BSP及嵌入式驱动开辟笔记 第一讲嵌入式系统基本概念 以应用为中央,以计算机 ...

  4. 迅为嵌入式linux驱动开发笔记(十一)—触摸屏驱动

    总结篇 这一小节内容是对之前学习的十节课进行总复习,综合性非常强,完成触摸屏驱动需要学会如下知识: 1.驱动开发原理 第一节 2.platform平台总线模型 第三节 3.设备树 第四节 4.gpio ...

  5. 嵌入式Linux驱动开发笔记(未完待续。。。)

    零.嵌入式Linux驱动编程思想 1.面向对象(把一个事件抽象成一个结构体) 2.分层 3.分离 一.Git仓库用法 1.linu终端输入下面命令安装 git clone https://e.codi ...

  6. ip核在linux的驱动,Linux驱动开发笔记:对zynq PL部分IP核的驱动开发过程

    reg_addr = (((hopcount+1) #include * Xilinx RapidIO 3. 驱动设计 } #include Amba_pl对应PL部分的amba,devicetree ...

  7. linux驱动开发笔记 一 基本流程

    linux驱动开发, 有特定的模式, 在我看来linux驱动只做了一件事, 将设备统一转换成了统一的3类虚拟设备 分别是: 1. 字符设备 2. 块设备 3. 网络设备 linux驱动开发, 需要在U ...

  8. Linux设备驱动开发笔记

    0 Linux 操作系统知识 Linux是一个操作系统. 优点: 免费: 丰富的文档和社区支持: 跨平台移植: 源代码开放: 有许多免费开源软件. 家用电脑用Windows,服务器端用Linux. 操 ...

  9. Windows打印机驱动开发笔记(一)

    在Windows中,打印机驱动的作用是编写一组接口.应用程序调用的GDI函数会变成相应的DDI函数,打印机驱动提供的这组接口负责将DDI函数转变为打印机识别的的指令.至于是通过网口.串口等接口与真实打 ...

  10. 驱动开发笔记5—驱动对象、设备对象、IRP和派遣函数

    文章目录 驱动对象 设备对象 IRP和派遣函数 IRP IRP类型 设置派遣函数 处理IRP 举例说明 设备读写方式 缓冲区方式读写 直接方式读写 其他方式读写 驱动对象 每个驱动程序都会有唯一的驱动 ...

最新文章

  1. 读取本地照片 以流的形式进行显示
  2. 「情报局41」人工智能的下一个目标是什么?了解业务用例
  3. 《城市大脑全球标准研究报告》发布会将于12月23号在北京举办
  4. 互联网广告综述之点击率特征工程
  5. dedecms后台左侧菜单500错误怎么处理
  6. Spring @Transactional (一)
  7. RIS镜像中添加网卡和RAID卡驱动方法及实践经验总结
  8. 蓝魔i11pro运行linux,不仅仅是变大了 蓝魔i11pro新玩法
  9. tableview cell自适应撑高
  10. 【IDEA】Command line is too long. Shorten command ... or also for Application default configuration
  11. 如何用prometheus监控k8s集群中业务pod的metrics
  12. 构建自己的NSZombie
  13. Xen调度分析-RT
  14. 码龄10年工作6年的搬砖小哥,最常访问的学习网站都在这里了
  15. Linux----常用操作
  16. sd卡计算机无法读取数据,细说电脑无法读取sd卡
  17. 计算机网络微课堂 学习笔记
  18. Chrome插件安装时出现的“程序包无效”问题
  19. SAP中销售订单计划行类别中请求/装配对物料需求计划的影响测试
  20. 软件著作权申请时间是多久?

热门文章

  1. 【异常解决】DolphinScheduler-2.0.5 工作流实例无法调度和停止异常
  2. 想要快速增肌?肌酸可以帮你高效获得肌肉和力量
  3. java对象为什么要实现序列化
  4. 最新封装版EVE模拟器部署和使用说明(图文版)
  5. 【牛客网】马三来刷题之顺时针旋转矩阵
  6. android item弹出popupwindow recycleview_PopupWindow+RecyclerView实现上下滑动框功能
  7. 软件开发未来五大技术趋势
  8. 互联网大数据时代下亚马逊是如何解决数据存储的
  9. 多家高校网站被挂马 用户应小心QQ盗号木马
  10. CC2650 入手资料总结(转)