日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MTK6573电源管理(PM)小结

發布時間:2025/4/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MTK6573电源管理(PM)小结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

繼續MTK平臺的研究

開始研究電源管理,因為PM永遠是嵌入式的核心技術,所以靜下來走一遍流程。

MTK啟動的過程:

硬件板載的啟動入口為

static __init int board_init(void)
{
??? mt6573_power_management_init();
??? mt6573_board_init();
??? return 0;
}


其中mt6573_board_init();的作用如下:

??????????????? mt6573_board_init() is used for chip-dependent code.
???? *????????? It is suggested to put driver code in this function to do:
???? *????????? 1). Capability structure of platform devices.
???? *????????? 2). Define platform devices with their resources.
???? *????????? 3). Register MT65XX platform devices.

即注冊各種devices 如:&pmem_multimedia_device,&mt6573_device_uart[i],&AudDrv_device,&mt6573_nand_dev,&kpd_pdev等等各種設備。

其中mt6573_power_management_init();初始化各種電源管理。下面是這個函數的源碼:

void mt6573_power_management_init(void)
{
??? /* Check Chip Version */
??? gChipVer = DRV_Reg32(APHW_VER);
??? printk("[%s]: gChipVer = 0x%x\r\n",__FUNCTION__, gChipVer);
??? /* Load DVFS, DCM Setting from Spare*/
??? mt6573_load_spare_settings();
??? /* Clock Gating init, gated un-necessary power*/
??? mt6573_CG_init();
??? /* Set specific chip setting*/
??? mt6573_chip_dep_init();??????? ?
??? /* Power mamagement log init*/
??? mt6573_log_init();
??? /* DCM init*/
??? mt6573_dcm_init();
??? /* Thermal protect Init*/
??? hwThermalProtectInit();
??? /* Sleep Controller init*/
??? slp_mod_init();
}

首先看mt6573_load_spare_settings();

void mt6573_load_spare_settings(void)
{
??? u16 spar0;
??? spar0 = 0;
??? if (spar0 & SPARE_SECRET_KEY)
??? {
??????? if(spar0 & SPARE_E1_PATCH)
??????????? gChipVer = CHIP_VER_E2;

??????? if(spar0 & SPARE_DVFS_EN)
??????????? bCanEnDVFS = TRUE;
??????? else
??????????? bCanEnDVFS = FALSE;

??????? if(spar0 & SPARE_VAPROC_ADJUST_EN)
??????????? bBUCK_ADJUST = TRUE;
??????? else
??????????? bBUCK_ADJUST = FALSE;

??????? if(spar0 & SPARE_DVFS_LOG)
??????????? bEnDVFSLog = TRUE;
??????? else
??????????? bEnDVFSLog = FALSE;
??? }
}
從代碼中看是加載備用設備,但spar0 = 0所以后面的代碼應該不會執行了。這是我個人的觀點,希望有提出意見的。拋開這個問題可以看出主要是讀標志位來給設的變量賦TURE or FALSE.

再看:mt6573_CG_init();

void mt6573_CG_init(void)
{
??? UINT32 u4Val;
??? struct cust_mt65xx_led *cust_led_list = get_cust_led_list();????????? //設置各種Led背光

??? set_clock_listen(TRUE);
??? DRV_SetReg32(APMCU_CG_CLR0, 0xffffffff);
??? ... ...

??? 后面設置一些設備模塊的時鐘
}

mt6573_chip_dep_init();? 設置芯片寄存器

。。。

重點看看sleep 控制器的初始化。

void slp_mod_init(void)
{
?? ?slp_pmu_init();

?? ?ost_mod_init();

?? ?suspend_set_ops(&slp_suspend_ops);

?? ?proc_create_data("slp_md_sta", 0444, NULL, &slp_md_sta_fops, NULL);
}

先看slp_pmu_init();

static void slp_pmu_init(void)
{
?? ?u16 con1;

#ifdef VCORE_1_1_V_IN_SLEEP
?? ?/* Vcore = 1.1V in sleep mode */
?? ?con1 = (slp_read16(VCORE_CON1) & 0xfe0f) | (28 << 4);
?? ?slp_write16(VCORE_CON1, con1);
#else
?? ?/* Vcore = 0.9V in sleep mode */
?? ?con1 = (slp_read16(VCORE_CON1) & 0xfe0f) | (20 << 4);
?? ?slp_write16(VCORE_CON1, con1);
#endif

?? ?/* Vaproc = 0.9V in sleep mode */
?? ?con1 = (slp_read16(VAPROC_CON1) & 0xfe0f) | (20 << 4);
?? ?slp_write16(VAPROC_CON1, con1);

?? ?/* clear CCI_SRCLKEN to enable HW sleep-mode control */
?? ?con1 = slp_read16(VA28_CON1) & ~(1U << 8);
?? ?slp_write16(VA28_CON1, con1);

?? ?slp_write_sync();
}
從代碼上看,當睡眠有兩種電壓模式,一種是1.1V,還有一種是0.9V。依據芯片具體用哪種電壓模式,然后寫入寄存器。

再看:suspend_set_ops(&slp_suspend_ops);

void suspend_set_ops(struct platform_suspend_ops *ops)
{
?? ?mutex_lock(&pm_mutex);
?? ?suspend_ops = ops;
?? ?mutex_unlock(&pm_mutex);
}

所以就是給slp_suspend_ops賦值就可以拉:

static struct platform_suspend_ops slp_suspend_ops = {
?? ?.valid?? ??? ?= slp_suspend_ops_valid,
?? ?.begin?? ??? ?= slp_suspend_ops_begin,
?? ?.prepare?? ?= slp_suspend_ops_prepare,
?? ?.enter?? ??? ?= slp_suspend_ops_enter,
?? ?.finish?? ??? ?= slp_suspend_ops_finish,
?? ?.end?? ??? ?= slp_suspend_ops_end,
};

即初始化這個數據結構里的成員函數

其中重要的函數是

static int slp_suspend_ops_enter(suspend_state_t state)
{
?? ?/* legacy log */
?? ?printk("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
?? ?printk("_Chip_pm_enter @@@@@@@@@@@@@@@@@@@@@@\n");
?? ?printk(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");

?? ?if (slp_dump_gpio)
?? ??? ?gpio_dump_regs();

?? ?if (get_chip_eco_ver() == CHIP_E1) {
?? ??? ?/* disable DCM to workaround EMI auto-refresh issue */
?? ??? ?MT6573_DISABLE_HW_DCM_AP();
?? ?} else {
?? ??? ?MT6573_ENABLE_HW_DCM_AP();
?? ?}

?? ?if (slp_dump_regs)
?? ??? ?slp_dump_pm_regs();

?? ?rtc_disable_writeif();

?? ?slp_wake_reason = ost_go_to_sleep();

?? ?rtc_enable_writeif();

?? ?MT6573_DISABLE_HW_DCM_AP();

?? ?return 0;
}

wake_reason_t ost_go_to_sleep(void)
{
?? ?int i;
?? ?unsigned long flags;
?? ?struct mtk_irq_mask mask;
?? ?wake_reason_t wr;

?? ?spin_lock_irqsave(&ost_lock, flags);
?? ?for (i = 0; i < NUM_WAKE_SRC; i++) {
?? ??? ?if (ost_wake_src & (1U << i))
?? ??? ??? ?ost_enable_wake_irq(ost_wake_irq[i], false);
?? ?}

?? ?mt6573_irq_mask_all(&mask);

?? ?ost_enable_wake_irq(MT6573_APOST_IRQ_LINE, true);

?? ?/* OST will periodically wake up */
?? ?wr = ost_enter_pwake_pause_mode();

?? ?mt6573_irq_mask_restore(&mask);
?? ?spin_unlock_irqrestore(&ost_lock, flags);

?? ?return wr;
}
static wake_reason_t __tcmfunc ost_enter_pwake_pause_mode(void)
{
?? ?u16 isr;
?? ?u32 ufn, wakesta;
?? ?unsigned long vbat, cnt = 0;

?? ?while (1) {
?? ??? ?ufn = ost_get_wake_period(cnt) * 1000000 / OST_FRM_VAL;
?? ??? ?ost_write32(OST_UFN, ufn);
?? ??? ?ost_write32(OST_AFN, 0);

?? ??? ?/* unmask wakeup sources */
?? ??? ?ost_write32(OST_EVENT_MASK, ~ost_wake_src);

?? ??? ?/* unmask Pause Interrupt, Pause Abort and UFN Timeout */
?? ??? ?ost_write32(OST_INT_MASK, 0x0003);

?? ??? ?ost_write16(OST_CON, OST_CON_UFN_DOWN | OST_CON_EN);
?? ??? ?ost_write32(OST_CMD, OST_CMD_KEY | OST_CMD_CON_WR | OST_CMD_AFN_WR |
?? ??? ????????????????????? OST_CMD_UFN_WR | OST_CMD_OST_WR);
?? ??? ?while (!(ost_read16(OST_STA) & OST_STA_CMD_CPL));

?? ??? ?ost_write32(OST_CMD, OST_CMD_KEY | OST_CMD_PAUSE_STR);
?? ??? ?while (!(ost_read16(OST_STA) & OST_STA_CMD_CPL));

?? ??? ?/* flush L1 and L2 store buffers */
?? ??? ?ost_write_sync();

?? ??? ?/* enter WFI mode */
?? ??? ?__asm__ __volatile__("mcr p15, 0, %0, c7, c0, 4" : : "r" (0));

?? ??? ?wakesta = ost_read32(OST_WAKEUP_STA);
?? ??? ?isr = ost_read16(OST_ISR);

?? ??? ?ost_write32(OST_INT_MASK, 0x001f);
?? ??? ?ost_write16(OST_ISR, 0x001f);?? ?/* write 1 clear */
?? ??? ?ost_write_sync();

?? ??? ?if (isr == 0x0004) {?? ?/* UFN Timeout */
?? ??? ??? ?vbat = BAT_Get_Battery_Voltage();
?? ??? ??? ?printk("vbat-%lu = %lu\n", ++cnt, vbat);
?? ??? ??? ?if (vbat <= SYSTEM_OFF_VOLTAGE) {
?? ??? ??? ??? ?printk("low battery => wake up\n");
?? ??? ??? ??? ?return WR_LOW_BAT;
?? ??? ??? ?}
?? ??? ?} else {
?? ??? ??? ?ost_output_wake_reason(wakesta, isr);
?? ??? ??? ?return WR_WAKE_SRC;
?? ??? ?}
?? ?}

?? ?return WR_NONE;
}
static void ost_output_wake_reason(u32 wakesta, u16 isr)
{
?? ?char str[128] = { 0 };

?? ?if (wakesta & WAKE_SRC_KP)
?? ??? ?strcat(str, "KP ");

?? ?if (wakesta & WAKE_SRC_MSDC0)
?? ??? ?strcat(str, "MSDC0 ");

?? ?if (wakesta & WAKE_SRC_EINT)
?? ??? ?strcat(str, "EINT ");

?? ?if (wakesta & WAKE_SRC_RTC)
?? ??? ?strcat(str, "RTC ");

?? ?if (wakesta & WAKE_SRC_CCIF_MD)
?? ??? ?strcat(str, "CCIF_MD ");

?? ?printk("wake up by %s(0x%x)(0x%x)\n", str, wakesta, isr);
}

這個函數是判斷機器是以何種方式喚醒的,比如:電源鍵,USB中斷,modem電話,時鐘等等。


函數?proc_create_data("slp_md_sta", 0444, NULL, &slp_md_sta_fops, NULL);

static struct file_operations slp_md_sta_fops = {
?? ?.open?? ??? ?= slp_md_sta_open,
?? ?.read?? ??? ?= seq_read,
?? ?.llseek?? ??? ?= seq_lseek,
?? ?.release?? ?= single_release,
};

總結

以上是生活随笔為你收集整理的MTK6573电源管理(PM)小结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产黄色片在线播放 | 在线观看免费视频国产 | 美女脱得一干二净 | 亚洲性猛交| 琪琪色综合 | 久久91久久| 欧美黄在线观看 | av免播放器在线观看 | 黑人精品无码一区二区三区 | 天堂网在线最新版www中文网 | 黄色一级在线播放 | 亚洲日本黄色 | 里番acg★同人里番本子大全 | 国产老头和老头xxxx× | 国产孕妇孕交大片孕 | 国产有码在线 | 粗大挺进潘金莲身体在线播放 | 亚洲乱码一区二区 | 69国产精品视频 | 中文字幕人妻丝袜二区 | 黄页网站在线 | 欧美日韩在线免费观看视频 | 欧美图片一区 | 成人手机视频在线观看 | 久久com | 久久免费国产 | 黄色天堂av | 激情婷婷六月 | 欧美a在线视频 | 亚洲三级黄色 | 中文字幕av在线免费观看 | 一级全黄裸体免费观看视频 | 色姐| 欧美z○zo重口另类黄 | 超级碰在线观看 | 二区中文字幕 | 五月伊人网 | 永久免费看片在线观看 | 综合色爱 | 国产乱淫av公 | 国产91在线观看丝袜 | 女优视频在线观看 | 久久久久国 | 国产精品--色哟哟 | 狠狠爱五月婷婷 | 在线观看自拍 | 诱夫1v1高h | 国产视频一区二区不卡 | 午夜国产精品视频 | 美女隐私免费 | 男女免费网站 | 99ri在线 | 99人人爽 | 乳揉みま痴汉4在线播放 | av观看网站 | 亚洲欧美小视频 | 高潮videossex高潮 | 国产精品美女久久久 | 深夜福利网 | 国产精品色图 | 国产精品情侣 | 狠狠操免费视频 | 国产精品久久久久影院老司 | jizz日本大全| 久久久亚洲欧洲 | 精品国产1区 | 国产裸体美女永久免费无遮挡 | 隣の若妻さん波多野结衣 | 午夜伦理一区二区 | 日韩在线不卡一区 | 少妇高潮一区二区三区69 | 九一爱爱 | 色欲久久久天天天精品综合网 | 少妇野外性xx老女人野外性xx | 91久色蝌蚪 | 一区二区三区网站 | 欧美日韩视频在线播放 | 欧美精品在线视频观看 | 高潮无码精品色欲av午夜福利 | 一区二区三区亚洲 | 成人av免费在线播放 | 久久99国产精品久久99果冻传媒 | 欧美50p| 尤物最新网址 | 夜夜撸小说 | 日本不卡在线播放 | 亚洲激情黄色 | 在线精品一区二区 | 国产激情无套内精对白视频 | 麻豆免费下载 | 国产交换配乱淫视频免费 | 色网站免费| 日韩毛片中文字幕 | 免费在线观看视频 | 午夜影院在线观看18 | 波多野结衣中文字幕在线播放 | 日本丰满熟妇hd | 亚洲青青操 | 色综合社区 |