| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/interrupt.h>
- #include <linux/semaphore.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
- #include <linux/printk.h>
- #define MET_USER_EVENT_SUPPORT
- /* #include <linux/met_drv.h> */
- #include <mt-plat/mt_io.h>
- #include <mt-plat/sync_write.h>
- #include "mach/emi_bwl.h"
- DEFINE_SEMAPHORE(emi_bwl_sem);
- void __iomem *EMI_BASE_ADDR = NULL;
- static struct platform_driver mem_bw_ctrl = {
- .driver = {
- .name = "mem_bw_ctrl",
- .owner = THIS_MODULE,
- },
- };
- static struct platform_driver ddr_type = {
- .driver = {
- .name = "ddr_type",
- .owner = THIS_MODULE,
- },
- };
- /* define EMI bandwiwth limiter control table */
- static struct emi_bwl_ctrl ctrl_tbl[NR_CON_SCE];
- /* current concurrency scenario */
- static int cur_con_sce = 0x0FFFFFFF;
- #if defined(CONFIG_ARCH_MT6735) && !defined(CONFIG_MTK_EMI_D1P)
- /* define concurrency scenario strings */
- static const char const *con_sce_str[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, \
- arbd, arbe, arbf, arbg2) (#con_sce),
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR2-1066******************/
- static const unsigned int emi_arba_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr2_1066_D1.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR3-1600******************/
- static const unsigned int emi_arba_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr3_1600_D1.h"
- #undef X_CON_SCE
- };
- #elif defined(CONFIG_ARCH_MT6735M)
- /* define concurrency scenario strings */
- static const char const *con_sce_str[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, \
- arbd, arbe, arbf, arbg2) (#con_sce),
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR2-1066******************/
- static const unsigned int emi_arba_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr2_1066_D2.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR3-1600******************/
- static const unsigned int emi_arba_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr3_1600_D2.h"
- #undef X_CON_SCE
- };
- #elif defined(CONFIG_ARCH_MT6753) || defined(CONFIG_MTK_EMI_D1P)
- /* define concurrency scenario strings */
- static const char const *con_sce_str[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, \
- arbd, arbe, arbf, arbg2) (#con_sce),
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR2-1066******************/
- static const unsigned int emi_arba_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr2_1066_D3.h"
- #undef X_CON_SCE
- };
- /****************** For LPDDR3-1600******************/
- static const unsigned int emi_arba_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbb_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbc_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbd_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbe_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbf_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
- #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
- #include "mach/con_sce_lpddr3_1600_D3.h"
- #undef X_CON_SCE
- };
- #endif
- int get_dram_type(void)
- {
- unsigned int value = ucDram_Register_Read(DRAMC_ACTIM1);
- if ((value >> 28) & 0x1)
- return LPDDR3_1600;
- else
- return LPDDR2_1066;
- }
- /*
- * mtk_mem_bw_ctrl: set EMI bandwidth limiter for memory bandwidth control
- * @sce: concurrency scenario ID
- * @op: either ENABLE_CON_SCE or DISABLE_CON_SCE
- * Return 0 for success; return negative values for failure.
- */
- int mtk_mem_bw_ctrl(int sce, int op)
- {
- int i, highest;
- if (sce >= NR_CON_SCE)
- return -1;
- if (op != ENABLE_CON_SCE && op != DISABLE_CON_SCE)
- return -1;
- if (in_interrupt())
- return -1;
- down(&emi_bwl_sem);
- if (op == ENABLE_CON_SCE)
- ctrl_tbl[sce].ref_cnt++;
- else if (op == DISABLE_CON_SCE) {
- if (ctrl_tbl[sce].ref_cnt != 0)
- ctrl_tbl[sce].ref_cnt--;
- }
- /* find the scenario with the highest priority */
- highest = -1;
- for (i = 0; i < NR_CON_SCE; i++) {
- if (ctrl_tbl[i].ref_cnt != 0) {
- highest = i;
- break;
- }
- }
- if (highest == -1)
- highest = CON_SCE_NORMAL;
- /* set new EMI bandwidth limiter value */
- if (highest != cur_con_sce) {
- if (get_dram_type() == LPDDR3_1600) {
- writel(emi_arba_lpddr3_1600_val[highest], EMI_ARBA);
- writel(emi_arbb_lpddr3_1600_val[highest], EMI_ARBB);
- writel(emi_arbc_lpddr3_1600_val[highest], EMI_ARBC);
- writel(emi_arbd_lpddr3_1600_val[highest], EMI_ARBD);
- writel(emi_arbe_lpddr3_1600_val[highest], EMI_ARBE);
- writel(emi_arbf_lpddr3_1600_val[highest], EMI_ARBF);
- mt_reg_sync_writel(emi_arbg2_lpddr3_1600_val[highest],
- EMI_ARBG_2ND);
- } else if (get_dram_type() == LPDDR2_1066) {
- writel(emi_arba_lpddr2_1066_val[highest], EMI_ARBA);
- writel(emi_arbb_lpddr2_1066_val[highest], EMI_ARBB);
- writel(emi_arbc_lpddr2_1066_val[highest], EMI_ARBC);
- writel(emi_arbd_lpddr2_1066_val[highest], EMI_ARBD);
- writel(emi_arbe_lpddr2_1066_val[highest], EMI_ARBE);
- writel(emi_arbf_lpddr2_1066_val[highest], EMI_ARBF);
- mt_reg_sync_writel(emi_arbg2_lpddr2_1066_val[highest],
- EMI_ARBG_2ND);
- }
- cur_con_sce = highest;
- }
- up(&emi_bwl_sem);
- /* met_show_bw_limiter(); */
- return 0;
- }
- /*
- * ddr_type_show: sysfs ddr_type file show function.
- * @driver:
- * @buf: the string of ddr type
- * Return the number of read bytes.
- */
- static ssize_t ddr_type_show(struct device_driver *driver, char *buf)
- {
- if (get_dram_type() == LPDDR3_1600)
- sprintf(buf, "LPDDR3_1600\n");
- else if (get_dram_type() == LPDDR2_1066)
- sprintf(buf, "LPDDR2_1066\n");
- return strlen(buf);
- }
- /*
- * ddr_type_store: sysfs ddr_type file store function.
- * @driver:
- * @buf:
- * @count:
- * Return the number of write bytes.
- */
- static ssize_t ddr_type_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- /*do nothing */
- return count;
- }
- DRIVER_ATTR(ddr_type, 0644, ddr_type_show, ddr_type_store);
- /*
- * con_sce_show: sysfs con_sce file show function.
- * @driver:
- * @buf:
- * Return the number of read bytes.
- */
- static ssize_t con_sce_show(struct device_driver *driver, char *buf)
- {
- char *ptr = buf;
- int i = 0;
- if (cur_con_sce >= NR_CON_SCE)
- ptr += sprintf(ptr, "none\n");
- else
- ptr += sprintf(ptr, "current scenario: %s\n",
- con_sce_str[cur_con_sce]);
- #if 1
- ptr += sprintf(ptr, "%s\n", con_sce_str[cur_con_sce]);
- ptr += sprintf(ptr, "EMI_ARBA = 0x%x\n", readl(IOMEM(EMI_ARBA)));
- ptr += sprintf(ptr, "EMI_ARBB = 0x%x\n", readl(IOMEM(EMI_ARBB)));
- ptr += sprintf(ptr, "EMI_ARBC = 0x%x\n", readl(IOMEM(EMI_ARBC)));
- ptr += sprintf(ptr, "EMI_ARBD = 0x%x\n", readl(IOMEM(EMI_ARBD)));
- ptr += sprintf(ptr, "EMI_ARBE = 0x%x\n", readl(IOMEM(EMI_ARBE)));
- ptr += sprintf(ptr, "EMI_ARBF = 0x%x\n", readl(IOMEM(EMI_ARBF)));
- ptr += sprintf(ptr, "EMI_ARBG = 0x%x\n", readl(IOMEM(EMI_ARBG_2ND)));
- for (i = 0; i < NR_CON_SCE; i++)
- ptr += sprintf(ptr, "%s = 0x%x\n", con_sce_str[i],
- ctrl_tbl[i].ref_cnt);
- pr_debug("[EMI BWL] EMI_ARBA = 0x%x\n", readl(IOMEM(EMI_ARBA)));
- pr_debug("[EMI BWL] EMI_ARBB = 0x%x\n", readl(IOMEM(EMI_ARBB)));
- pr_debug("[EMI BWL] EMI_ARBC = 0x%x\n", readl(IOMEM(EMI_ARBC)));
- pr_debug("[EMI BWL] EMI_ARBD = 0x%x\n", readl(IOMEM(EMI_ARBD)));
- pr_debug("[EMI BWL] EMI_ARBE = 0x%x\n", readl(IOMEM(EMI_ARBE)));
- pr_debug("[EMI BWL] EMI_ARBF = 0x%x\n", readl(IOMEM(EMI_ARBF)));
- pr_debug("[EMI BWL] EMI_ARBG = 0x%x\n", readl(IOMEM(EMI_ARBG_2ND)));
- #endif
- return strlen(buf);
- }
- /*
- * con_sce_store: sysfs con_sce file store function.
- * @driver:
- * @buf:
- * @count:
- * Return the number of write bytes.
- */
- static ssize_t con_sce_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- int i;
- for (i = 0; i < NR_CON_SCE; i++) {
- if (!strncmp(buf, con_sce_str[i], strlen(con_sce_str[i]))) {
- if (!strncmp
- (buf + strlen(con_sce_str[i]) + 1, EN_CON_SCE_STR,
- strlen(EN_CON_SCE_STR))) {
- mtk_mem_bw_ctrl(i, ENABLE_CON_SCE);
- pr_debug("concurrency scenario %s ON\n",
- con_sce_str[i]);
- break;
- } else if (!strncmp(buf + strlen(con_sce_str[i]) + 1,
- DIS_CON_SCE_STR, strlen(DIS_CON_SCE_STR))) {
- mtk_mem_bw_ctrl(i, DISABLE_CON_SCE);
- pr_debug("concurrency scenario %s OFF\n",
- con_sce_str[i]);
- break;
- }
- }
- }
- return count;
- }
- DRIVER_ATTR(concurrency_scenario, 0644, con_sce_show, con_sce_store);
- /*
- * emi_bwl_mod_init: module init function.
- */
- static int __init emi_bwl_mod_init(void)
- {
- int ret;
- struct device_node *node;
- /* DTS version */
- if (EMI_BASE_ADDR == NULL) {
- node = of_find_compatible_node(NULL, NULL, "mediatek,EMI");
- if (node) {
- EMI_BASE_ADDR = of_iomap(node, 0);
- pr_err("get EMI_BASE_ADDR @ %p\n", EMI_BASE_ADDR);
- } else {
- pr_err("can't find compatible node\n");
- return -1;
- }
- }
- ret = mtk_mem_bw_ctrl(CON_SCE_NORMAL, ENABLE_CON_SCE);
- if (ret)
- pr_err("[EMI/BWL] fail to set EMI bandwidth limiter\n");
- /* Register BW ctrl interface */
- ret = platform_driver_register(&mem_bw_ctrl);
- if (ret)
- pr_err("[EMI/BWL] fail to register EMI_BW_LIMITER driver\n");
- ret = driver_create_file(&mem_bw_ctrl.driver,
- &driver_attr_concurrency_scenario);
- if (ret)
- pr_err("[EMI/BWL] fail to create EMI_BW_LIMITER sysfs file\n");
- /* Register DRAM type information interface */
- ret = platform_driver_register(&ddr_type);
- if (ret)
- pr_err("[EMI/BWL] fail to register DRAM_TYPE driver\n");
- ret = driver_create_file(&ddr_type.driver, &driver_attr_ddr_type);
- if (ret)
- pr_err("[EMI/BWL] fail to create DRAM_TYPE sysfs file\n");
- return 0;
- }
- /*
- * emi_bwl_mod_exit: module exit function.
- */
- static void __exit emi_bwl_mod_exit(void)
- {
- }
- /* EXPORT_SYMBOL(get_dram_type); */
- late_initcall(emi_bwl_mod_init);
- module_exit(emi_bwl_mod_exit);
|