1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/interrupt.h>
4 #include <linux/semaphore.h>
5 #include <linux/device.h>
6 #include <linux/platform_device.h>
7 #include <linux/xlog.h>
9 #include "mach/mt_reg_base.h"
10 #include "mach/emi_bwl.h"
11 #include "mach/sync_write.h"
13 DEFINE_SEMAPHORE(emi_bwl_sem
);
15 static struct platform_driver mem_bw_ctrl
= {
17 .name
= "mem_bw_ctrl",
22 static struct platform_driver ddr_type
= {
31 static struct platform_driver dramc_high
= {
38 static struct platform_driver mem_bw_finetune_md
= {
40 .name
= "mem_bw_finetune_md",
45 static struct platform_driver mem_bw_finetune_mm
= {
47 .name
= "mem_bw_finetune_mm",
53 /* define EMI bandwiwth limiter control table */
54 static struct emi_bwl_ctrl ctrl_tbl
[NR_CON_SCE
];
56 /* current concurrency scenario */
57 static int cur_con_sce
= 0x0FFFFFFF;
59 /* define concurrency scenario strings */
60 static const char *con_sce_str
[] =
62 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) #con_sce,
63 #include "mach/con_sce_lpddr2.h"
67 /* define EMI bandwidth allocation tables */
68 /****************** For LPDDR2 ******************/
69 static const unsigned int emi_arba_lpddr2_val
[] =
71 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arba,
72 #include "mach/con_sce_lpddr2.h"
76 static const unsigned int emi_arbb_lpddr2_val
[] =
78 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbb,
79 #include "mach/con_sce_lpddr2.h"
82 static const unsigned int emi_arbc_lpddr2_val
[] =
84 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbc,
85 #include "mach/con_sce_lpddr2.h"
88 static const unsigned int emi_arbd_lpddr2_val
[] =
90 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbd,
91 #include "mach/con_sce_lpddr2.h"
94 static const unsigned int emi_arbe_lpddr2_val
[] =
96 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbe,
97 #include "mach/con_sce_lpddr2.h"
101 /****************** For DDR3-16bit ******************/
103 static const unsigned int emi_arba_ddr3_16_val
[] =
105 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arba,
106 #include "mach/con_sce_ddr3_16.h"
110 static const unsigned int emi_arbb_ddr3_16_val
[] =
112 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbb,
113 #include "mach/con_sce_ddr3_16.h"
116 static const unsigned int emi_arbc_ddr3_16_val
[] =
118 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbc,
119 #include "mach/con_sce_ddr3_16.h"
122 static const unsigned int emi_arbd_ddr3_16_val
[] =
124 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbd,
125 #include "mach/con_sce_ddr3_16.h"
128 static const unsigned int emi_arbe_ddr3_16_val
[] =
130 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbe,
131 #include "mach/con_sce_ddr3_16.h"
135 /****************** For LPDDR3 ******************/
137 static const unsigned int emi_arba_lpddr3_val
[] =
139 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arba,
140 #include "mach/con_sce_lpddr3.h"
144 static const unsigned int emi_arbb_lpddr3_val
[] =
146 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbb,
147 #include "mach/con_sce_lpddr3.h"
150 static const unsigned int emi_arbc_lpddr3_val
[] =
152 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbc,
153 #include "mach/con_sce_lpddr3.h"
156 static const unsigned int emi_arbd_lpddr3_val
[] =
158 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbd,
159 #include "mach/con_sce_lpddr3.h"
162 static const unsigned int emi_arbe_lpddr3_val
[] =
164 #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe) arbe,
165 #include "mach/con_sce_lpddr3.h"
169 int get_ddr_type(void)
173 value
= DRAMC_READ(DRAMC_LPDDR2
);
174 if((value
>>28) & 0x1) //check LPDDR2_EN
179 value
= DRAMC_READ(DRAMC_PADCTL4
);
180 if((value
>>7) & 0x1) //check DDR3_EN
182 if (DRAMC_READ(DRAMC_CONF1
) & 0x1)
192 value
= DRAMC_READ(DRAMC_ACTIM1
);
193 if((value
>>28) & 0x1) //check LPDDR3_EN
202 * mtk_mem_bw_ctrl: set EMI bandwidth limiter for memory bandwidth control
203 * @sce: concurrency scenario ID
204 * @op: either ENABLE_CON_SCE or DISABLE_CON_SCE
205 * Return 0 for success; return negative values for failure.
207 int mtk_mem_bw_ctrl(int sce
, int op
)
211 if (sce
>= NR_CON_SCE
) {
215 if (op
!= ENABLE_CON_SCE
&& op
!= DISABLE_CON_SCE
) {
218 if (in_interrupt()) {
224 if (op
== ENABLE_CON_SCE
) {
225 ctrl_tbl
[sce
].ref_cnt
++;
227 else if (op
== DISABLE_CON_SCE
) {
228 if (ctrl_tbl
[sce
].ref_cnt
!= 0) {
229 ctrl_tbl
[sce
].ref_cnt
--;
233 /* find the scenario with the highest priority */
235 for (i
= 0; i
< NR_CON_SCE
; i
++) {
236 if (ctrl_tbl
[i
].ref_cnt
!= 0) {
242 highest
= CON_SCE_NORMAL
;
245 /* set new EMI bandwidth limiter value */
246 if (highest
!= cur_con_sce
) {
249 if(get_ddr_type() == LPDDR2
)
251 mt65xx_reg_sync_writel(emi_arba_lpddr2_val
[highest
], EMI_ARBA
);
252 mt65xx_reg_sync_writel(emi_arbb_lpddr2_val
[highest
], EMI_ARBB
);
253 mt65xx_reg_sync_writel(emi_arbc_lpddr2_val
[highest
], EMI_ARBC
);
254 mt65xx_reg_sync_writel(emi_arbd_lpddr2_val
[highest
], EMI_ARBD
);
255 mt65xx_reg_sync_writel(emi_arbe_lpddr2_val
[highest
], EMI_ARBE
);
257 else if(get_ddr_type() == DDR3_16
)
259 mt65xx_reg_sync_writel(emi_arba_ddr3_16_val
[highest
], EMI_ARBA
);
260 mt65xx_reg_sync_writel(emi_arbb_ddr3_16_val
[highest
], EMI_ARBB
);
261 mt65xx_reg_sync_writel(emi_arbc_ddr3_16_val
[highest
], EMI_ARBC
);
262 mt65xx_reg_sync_writel(emi_arbd_ddr3_16_val
[highest
], EMI_ARBD
);
263 mt65xx_reg_sync_writel(emi_arbe_ddr3_16_val
[highest
], EMI_ARBE
);
265 else if(get_ddr_type() == LPDDR3
)
267 mt65xx_reg_sync_writel(emi_arba_lpddr3_val
[highest
], EMI_ARBA
);
268 mt65xx_reg_sync_writel(emi_arba_lpddr3_val
[highest
], EMI_ARBB
);
269 mt65xx_reg_sync_writel(emi_arba_lpddr3_val
[highest
], EMI_ARBC
);
270 mt65xx_reg_sync_writel(emi_arba_lpddr3_val
[highest
], EMI_ARBD
);
271 mt65xx_reg_sync_writel(emi_arba_lpddr3_val
[highest
], EMI_ARBE
);
274 cur_con_sce
= highest
;
283 * ddr_type_show: sysfs ddr_type file show function.
285 * @buf: the string of ddr type
286 * Return the number of read bytes.
288 static ssize_t
ddr_type_show(struct device_driver
*driver
, char *buf
)
290 if(get_ddr_type() == LPDDR2
)
292 sprintf(buf
, "LPDDR2\n");
294 else if(get_ddr_type() == DDR3_16
)
296 sprintf(buf
, "DDR3_16\n");
298 else if(get_ddr_type() == DDR3_32
)
300 sprintf(buf
, "DDR3_32\n");
302 else if(get_ddr_type() == LPDDR3
)
304 sprintf(buf
, "LPDDR3\n");
308 sprintf(buf
, "mDDR\n");
315 * ddr_type_store: sysfs ddr_type file store function.
319 * Return the number of write bytes.
321 static ssize_t
ddr_type_store(struct device_driver
*driver
, const char *buf
, size_t count
)
327 DRIVER_ATTR(ddr_type
, 0644, ddr_type_show
, ddr_type_store
);
330 * con_sce_show: sysfs con_sce file show function.
333 * Return the number of read bytes.
335 static ssize_t
con_sce_show(struct device_driver
*driver
, char *buf
)
337 if (cur_con_sce
>= NR_CON_SCE
) {
338 sprintf(buf
, "none\n");
340 sprintf(buf
, "%s\n", con_sce_str
[cur_con_sce
]);
347 * con_sce_store: sysfs con_sce file store function.
351 * Return the number of write bytes.
353 static ssize_t
con_sce_store(struct device_driver
*driver
, const char *buf
, size_t count
)
357 for (i
= 0; i
< NR_CON_SCE
; i
++) {
358 if (!strncmp(buf
, con_sce_str
[i
], strlen(con_sce_str
[i
]))) {
359 if (!strncmp(buf
+ strlen(con_sce_str
[i
]) + 1, EN_CON_SCE_STR
, strlen(EN_CON_SCE_STR
))) {
360 mtk_mem_bw_ctrl(i
, ENABLE_CON_SCE
);
361 printk("concurrency scenario %s ON\n", con_sce_str
[i
]);
364 else if (!strncmp(buf
+ strlen(con_sce_str
[i
]) + 1, DIS_CON_SCE_STR
, strlen(DIS_CON_SCE_STR
))) {
365 mtk_mem_bw_ctrl(i
, DISABLE_CON_SCE
);
366 printk("concurrency scenario %s OFF\n", con_sce_str
[i
]);
375 DRIVER_ATTR(concurrency_scenario
, 0644, con_sce_show
, con_sce_store
);
379 * finetune_md_show: sysfs con_sce file show function.
382 * Return the number of read bytes.
384 static ssize_t
finetune_md_show(struct device_driver
*driver
, char *buf
)
386 unsigned int dram_type
;
388 dram_type
= get_ddr_type();
390 if(dram_type
== LPDDR2
) /*LPDDR2. FIXME*/
395 sprintf(buf
, "true");
398 sprintf(buf
, "false");
402 else if(dram_type
== DDR3_16
) /*DDR3-16bit. FIXME*/
406 else if(dram_type
== DDR3_32
) /*DDR3-32bit. FIXME*/
410 else if(dram_type
== mDDR
) /*mDDR. FIXME*/
417 sprintf(buf
, "ERROR: unkown dram type!");
424 * finetune_md_store: sysfs con_sce file store function.
428 * Return the number of write bytes.
430 static ssize_t
finetune_md_store(struct device_driver
*driver
, const char *buf
, size_t count
)
436 DRIVER_ATTR(finetune_md
, 0644, finetune_md_show
, finetune_md_store
);
440 * finetune_mm_show: sysfs con_sce file show function.
443 * Return the number of read bytes.
445 static ssize_t
finetune_mm_show(struct device_driver
*driver
, char *buf
)
447 unsigned int dram_type
;
449 dram_type
= get_ddr_type();
451 if(dram_type
== LPDDR2
) /*LPDDR2. FIXME*/
456 sprintf(buf
, "false");
460 else if(dram_type
== DDR3_16
) /*DDR3-16bit. FIXME*/
464 else if(dram_type
== DDR3_32
) /*DDR3-32bit. FIXME*/
468 else if(dram_type
== mDDR
) /*mDDR. FIXME*/
475 sprintf(buf
, "ERROR: unkown dram type!");
482 * finetune_md_store: sysfs con_sce file store function.
486 * Return the number of write bytes.
488 static ssize_t
finetune_mm_store(struct device_driver
*driver
, const char *buf
, size_t count
)
494 DRIVER_ATTR(finetune_mm
, 0644, finetune_mm_show
, finetune_mm_store
);
498 * dramc_high_show: show the status of DRAMC_HI_EN
501 * Return the number of read bytes.
503 static ssize_t
dramc_high_show(struct device_driver
*driver
, char *buf
)
505 unsigned int dramc_hi
;
507 dramc_hi
= (readl(EMI_TESTB
) >> 12) & 0x1;
509 return sprintf(buf
, "DRAMC_HI is ON\n");
511 return sprintf(buf
, "DRAMC_HI is OFF\n");
515 dramc_hign_store: enable/disable DRAMC untra high. WARNING: ONLY CAN BE ENABLED AT MD_STANDALONE!!!
517 * @buf: need to be "0" or "1"
519 * Return the number of write bytes.
521 static ssize_t
dramc_high_store(struct device_driver
*driver
, const char *buf
, size_t count
)
524 unsigned int emi_testb
;
526 if (sscanf(buf
, "%u", &value
) != 1)
529 emi_testb
= readl(EMI_TESTB
);
533 emi_testb
|= 0x1000; /* Enable DRAM_HI */
534 mt65xx_reg_sync_writel(emi_testb
, EMI_TESTB
);
538 emi_testb
&= ~0x1000; /* Disable DRAM_HI */
539 mt65xx_reg_sync_writel(emi_testb
, EMI_TESTB
);
547 DRIVER_ATTR(dramc_high
, 0644, dramc_high_show
, dramc_high_store
);
550 * emi_bwl_mod_init: module init function.
552 static int __init
emi_bwl_mod_init(void)
557 if(get_ddr_type() == LPDDR2
) //LPDDR2
559 /* apply co-sim result for LPDDR2. */
560 mt65xx_reg_sync_writel(0x14212836, EMI_CONB
);
561 mt65xx_reg_sync_writel(0x0f131314, EMI_CONC
);
562 mt65xx_reg_sync_writel(0x14212836, EMI_COND
);
563 mt65xx_reg_sync_writel(0x0f131314, EMI_CONE
);
564 mt65xx_reg_sync_writel(0x0f131428, EMI_CONG
);
565 mt65xx_reg_sync_writel(0x0f131428, EMI_CONH
);
566 /* testing for MD2 timing fail */
567 mt65xx_reg_sync_writel(0x0c8f0ccd, EMI_SLCT
);
568 //mt65xx_reg_sync_writel(0x088b08cd, EMI_SLCT);
569 mt65xx_reg_sync_writel(0x00720038, EMI_ARBK
);
570 mt65xx_reg_sync_writel(0x00720038, EMI_ARBK_2ND
);
571 mt65xx_reg_sync_writel(0x84462f2f, EMI_ARBJ
);
572 mt65xx_reg_sync_writel(0x84462f2f, EMI_ARBJ_2ND
);
573 mt65xx_reg_sync_writel(0x10202488, EMI_ARBI
);
574 mt65xx_reg_sync_writel(0x10202488, EMI_ARBI_2ND
);
575 mt65xx_reg_sync_writel(0x00070714, EMI_TESTB
);
576 //mt65xx_reg_sync_writel(0x00070754, EMI_TESTB);
577 //mt65xx_reg_sync_writel(0x10000000, EMI_TESTD);
580 else if(get_ddr_type() == DDR3_16
) //DDR3-16bit
582 //write overhead value
583 mt65xx_reg_sync_writel(0x0B0B0E17, EMI_CONB
); //read overhead for 4~1
584 mt65xx_reg_sync_writel(0x0B0B0B0B, EMI_CONC
); //read overhead for 8~5
585 mt65xx_reg_sync_writel(0x1012161E, EMI_COND
); //write overhead for 4~1
586 mt65xx_reg_sync_writel(0x0B0B0D0E, EMI_CONE
); //write overhead for 8~5
588 else if(get_ddr_type() == DDR3_32
)
590 /* apply co-sim result for LPDDR2. */
591 mt65xx_reg_sync_writel(0x14212836, EMI_CONB
);
592 mt65xx_reg_sync_writel(0x0f131314, EMI_CONC
);
593 mt65xx_reg_sync_writel(0x14212836, EMI_COND
);
594 mt65xx_reg_sync_writel(0x0f131314, EMI_CONE
);
595 mt65xx_reg_sync_writel(0x0f131428, EMI_CONG
);
596 mt65xx_reg_sync_writel(0x0f131428, EMI_CONH
);
597 /* testing for MD2 timing fail */
598 mt65xx_reg_sync_writel(0x088b08cd, EMI_SLCT
);
599 mt65xx_reg_sync_writel(0x00720038, EMI_ARBK
);
600 mt65xx_reg_sync_writel(0x00720038, EMI_ARBK_2ND
);
601 mt65xx_reg_sync_writel(0x84462f2f, EMI_ARBJ
);
602 mt65xx_reg_sync_writel(0x84462f2f, EMI_ARBJ_2ND
);
603 mt65xx_reg_sync_writel(0x10202488, EMI_ARBI
);
604 mt65xx_reg_sync_writel(0x10202488, EMI_ARBI_2ND
);
605 mt65xx_reg_sync_writel(0x00070714, EMI_TESTB
);
606 //mt65xx_reg_sync_writel(0x00070754, EMI_TESTB);
607 //mt65xx_reg_sync_writel(0x10000000, EMI_TESTD);
609 else if(get_ddr_type() == LPDDR3
)
615 mt65xx_reg_sync_writel(0x2B2C2C2E, EMI_CONB
); //read overhead for 4~1
616 mt65xx_reg_sync_writel(0x2627292B, EMI_CONC
); //read overhead for 8~5
617 mt65xx_reg_sync_writel(0x2B2C2C2E, EMI_COND
); //write overhead for 4~1
618 mt65xx_reg_sync_writel(0x2627292B, EMI_CONE
); //write overhead for 8~5
622 //write Filter Priority Encode
623 //writel(0x01812488, EMI_ARBI); //TBD. need to set EMI_ARBI_2ND???
625 ret
= mtk_mem_bw_ctrl(CON_SCE_NORMAL
, ENABLE_CON_SCE
);
627 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to set EMI bandwidth limiter\n");
630 /* Register BW ctrl interface */
631 ret
= platform_driver_register(&mem_bw_ctrl
);
633 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to register EMI_BW_LIMITER driver\n");
636 ret
= driver_create_file(&mem_bw_ctrl
.driver
, &driver_attr_concurrency_scenario
);
638 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to create EMI_BW_LIMITER sysfs file\n");
641 /* Register DRAM type information interface */
642 ret
= platform_driver_register(&ddr_type
);
644 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to register DRAM_TYPE driver\n");
647 ret
= driver_create_file(&ddr_type
.driver
, &driver_attr_ddr_type
);
649 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to create DRAM_TYPE sysfs file\n");
652 /* Register DRAMC ultra high interface */
653 ret
= platform_driver_register(&dramc_high
);
654 ret
= driver_create_file(&dramc_high
.driver
, &driver_attr_dramc_high
);
656 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to create DRAMC_HIGH sysfs file\n");
660 /* Register MD feature fine-tune interface */
661 ret
= platform_driver_register(&mem_bw_finetune_md
);
663 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to register EMI_BW_FINETUNE_MD driver\n");
666 ret
= driver_create_file(&mem_bw_finetune_md
.driver
, &driver_attr_finetune_md
);
668 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to create EMI_BW_FINETUNE_MD sysfs file\n");
671 /* Register MM feature fine-tune interface */
672 ret
= platform_driver_register(&mem_bw_finetune_mm
);
674 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to register EMI_BW_FINETUNE_MM driver\n");
677 ret
= driver_create_file(&mem_bw_finetune_mm
.driver
, &driver_attr_finetune_mm
);
679 xlog_printk(ANDROID_LOG_ERROR
, "EMI/BWL", "fail to create EMI_BW_FINETUNE_MM sysfs file\n");
687 * emi_bwl_mod_exit: module exit function.
689 static void __exit
emi_bwl_mod_exit(void)
693 EXPORT_SYMBOL(get_ddr_type
);
695 module_init(emi_bwl_mod_init
);
696 module_exit(emi_bwl_mod_exit
);