Root/drivers/devfreq/exynos4_bus.c

1/* drivers/devfreq/exynos4210_memorybus.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework
8 * This version supports EXYNOS4210 only. This changes bus frequencies
9 * and vddint voltages. Exynos4412/4212 should be able to be supported
10 * with minor modifications.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/io.h>
19#include <linux/slab.h>
20#include <linux/mutex.h>
21#include <linux/suspend.h>
22#include <linux/opp.h>
23#include <linux/devfreq.h>
24#include <linux/platform_device.h>
25#include <linux/regulator/consumer.h>
26#include <linux/module.h>
27
28/* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
29#ifdef CONFIG_EXYNOS_ASV
30extern unsigned int exynos_result_of_asv;
31#endif
32
33#include <mach/regs-clock.h>
34
35#include <plat/map-s5p.h>
36
37#define MAX_SAFEVOLT 1200000 /* 1.2V */
38
39enum exynos4_busf_type {
40    TYPE_BUSF_EXYNOS4210,
41    TYPE_BUSF_EXYNOS4x12,
42};
43
44/* Assume that the bus is saturated if the utilization is 40% */
45#define BUS_SATURATION_RATIO 40
46
47enum ppmu_counter {
48    PPMU_PMNCNT0 = 0,
49    PPMU_PMCCNT1,
50    PPMU_PMNCNT2,
51    PPMU_PMNCNT3,
52    PPMU_PMNCNT_MAX,
53};
54struct exynos4_ppmu {
55    void __iomem *hw_base;
56    unsigned int ccnt;
57    unsigned int event;
58    unsigned int count[PPMU_PMNCNT_MAX];
59    bool ccnt_overflow;
60    bool count_overflow[PPMU_PMNCNT_MAX];
61};
62
63enum busclk_level_idx {
64    LV_0 = 0,
65    LV_1,
66    LV_2,
67    LV_3,
68    LV_4,
69    _LV_END
70};
71#define EX4210_LV_MAX LV_2
72#define EX4x12_LV_MAX LV_4
73#define EX4210_LV_NUM (LV_2 + 1)
74#define EX4x12_LV_NUM (LV_4 + 1)
75
76struct busfreq_data {
77    enum exynos4_busf_type type;
78    struct device *dev;
79    struct devfreq *devfreq;
80    bool disabled;
81    struct regulator *vdd_int;
82    struct regulator *vdd_mif; /* Exynos4412/4212 only */
83    struct opp *curr_opp;
84    struct exynos4_ppmu dmc[2];
85
86    struct notifier_block pm_notifier;
87    struct mutex lock;
88
89    /* Dividers calculated at boot/probe-time */
90    unsigned int dmc_divtable[_LV_END]; /* DMC0 */
91    unsigned int top_divtable[_LV_END];
92};
93
94struct bus_opp_table {
95    unsigned int idx;
96    unsigned long clk;
97    unsigned long volt;
98};
99
100/* 4210 controls clock of mif and voltage of int */
101static struct bus_opp_table exynos4210_busclk_table[] = {
102    {LV_0, 400000, 1150000},
103    {LV_1, 267000, 1050000},
104    {LV_2, 133000, 1025000},
105    {0, 0, 0},
106};
107
108/*
109 * MIF is the main control knob clock for exynox4x12 MIF/INT
110 * clock and voltage of both mif/int are controlled.
111 */
112static struct bus_opp_table exynos4x12_mifclk_table[] = {
113    {LV_0, 400000, 1100000},
114    {LV_1, 267000, 1000000},
115    {LV_2, 160000, 950000},
116    {LV_3, 133000, 950000},
117    {LV_4, 100000, 950000},
118    {0, 0, 0},
119};
120
121/*
122 * INT is not the control knob of 4x12. LV_x is not meant to represent
123 * the current performance. (MIF does)
124 */
125static struct bus_opp_table exynos4x12_intclk_table[] = {
126    {LV_0, 200000, 1000000},
127    {LV_1, 160000, 950000},
128    {LV_2, 133000, 925000},
129    {LV_3, 100000, 900000},
130    {0, 0, 0},
131};
132
133/* TODO: asv volt definitions are "__initdata"? */
134/* Some chips have different operating voltages */
135static unsigned int exynos4210_asv_volt[][EX4210_LV_NUM] = {
136    {1150000, 1050000, 1050000},
137    {1125000, 1025000, 1025000},
138    {1100000, 1000000, 1000000},
139    {1075000, 975000, 975000},
140    {1050000, 950000, 950000},
141};
142
143static unsigned int exynos4x12_mif_step_50[][EX4x12_LV_NUM] = {
144    /* 400 267 160 133 100 */
145    {1050000, 950000, 900000, 900000, 900000}, /* ASV0 */
146    {1050000, 950000, 900000, 900000, 900000}, /* ASV1 */
147    {1050000, 950000, 900000, 900000, 900000}, /* ASV2 */
148    {1050000, 900000, 900000, 900000, 900000}, /* ASV3 */
149    {1050000, 900000, 900000, 900000, 850000}, /* ASV4 */
150    {1050000, 900000, 900000, 850000, 850000}, /* ASV5 */
151    {1050000, 900000, 850000, 850000, 850000}, /* ASV6 */
152    {1050000, 900000, 850000, 850000, 850000}, /* ASV7 */
153    {1050000, 900000, 850000, 850000, 850000}, /* ASV8 */
154};
155
156static unsigned int exynos4x12_int_volt[][EX4x12_LV_NUM] = {
157    /* 200 160 133 100 */
158    {1000000, 950000, 925000, 900000}, /* ASV0 */
159    {975000, 925000, 925000, 900000}, /* ASV1 */
160    {950000, 925000, 900000, 875000}, /* ASV2 */
161    {950000, 900000, 900000, 875000}, /* ASV3 */
162    {925000, 875000, 875000, 875000}, /* ASV4 */
163    {900000, 850000, 850000, 850000}, /* ASV5 */
164    {900000, 850000, 850000, 850000}, /* ASV6 */
165    {900000, 850000, 850000, 850000}, /* ASV7 */
166    {900000, 850000, 850000, 850000}, /* ASV8 */
167};
168
169/*** Clock Divider Data for Exynos4210 ***/
170static unsigned int exynos4210_clkdiv_dmc0[][8] = {
171    /*
172     * Clock divider value for following
173     * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
174     * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
175     */
176
177    /* DMC L0: 400MHz */
178    { 3, 1, 1, 1, 1, 1, 3, 1 },
179    /* DMC L1: 266.7MHz */
180    { 4, 1, 1, 2, 1, 1, 3, 1 },
181    /* DMC L2: 133MHz */
182    { 5, 1, 1, 5, 1, 1, 3, 1 },
183};
184static unsigned int exynos4210_clkdiv_top[][5] = {
185    /*
186     * Clock divider value for following
187     * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
188     */
189    /* ACLK200 L0: 200MHz */
190    { 3, 7, 4, 5, 1 },
191    /* ACLK200 L1: 160MHz */
192    { 4, 7, 5, 6, 1 },
193    /* ACLK200 L2: 133MHz */
194    { 5, 7, 7, 7, 1 },
195};
196static unsigned int exynos4210_clkdiv_lr_bus[][2] = {
197    /*
198     * Clock divider value for following
199     * { DIVGDL/R, DIVGPL/R }
200     */
201    /* ACLK_GDL/R L1: 200MHz */
202    { 3, 1 },
203    /* ACLK_GDL/R L2: 160MHz */
204    { 4, 1 },
205    /* ACLK_GDL/R L3: 133MHz */
206    { 5, 1 },
207};
208
209/*** Clock Divider Data for Exynos4212/4412 ***/
210static unsigned int exynos4x12_clkdiv_dmc0[][6] = {
211    /*
212     * Clock divider value for following
213     * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
214     * DIVDMCP}
215     */
216
217    /* DMC L0: 400MHz */
218    {3, 1, 1, 1, 1, 1},
219    /* DMC L1: 266.7MHz */
220    {4, 1, 1, 2, 1, 1},
221    /* DMC L2: 160MHz */
222    {5, 1, 1, 4, 1, 1},
223    /* DMC L3: 133MHz */
224    {5, 1, 1, 5, 1, 1},
225    /* DMC L4: 100MHz */
226    {7, 1, 1, 7, 1, 1},
227};
228static unsigned int exynos4x12_clkdiv_dmc1[][6] = {
229    /*
230     * Clock divider value for following
231     * { G2DACP, DIVC2C, DIVC2C_ACLK }
232     */
233
234    /* DMC L0: 400MHz */
235    {3, 1, 1},
236    /* DMC L1: 266.7MHz */
237    {4, 2, 1},
238    /* DMC L2: 160MHz */
239    {5, 4, 1},
240    /* DMC L3: 133MHz */
241    {5, 5, 1},
242    /* DMC L4: 100MHz */
243    {7, 7, 1},
244};
245static unsigned int exynos4x12_clkdiv_top[][5] = {
246    /*
247     * Clock divider value for following
248     * { DIVACLK266_GPS, DIVACLK100, DIVACLK160,
249        DIVACLK133, DIVONENAND }
250     */
251
252    /* ACLK_GDL/R L0: 200MHz */
253    {2, 7, 4, 5, 1},
254    /* ACLK_GDL/R L1: 200MHz */
255    {2, 7, 4, 5, 1},
256    /* ACLK_GDL/R L2: 160MHz */
257    {4, 7, 5, 7, 1},
258    /* ACLK_GDL/R L3: 133MHz */
259    {4, 7, 5, 7, 1},
260    /* ACLK_GDL/R L4: 100MHz */
261    {7, 7, 7, 7, 1},
262};
263static unsigned int exynos4x12_clkdiv_lr_bus[][2] = {
264    /*
265     * Clock divider value for following
266     * { DIVGDL/R, DIVGPL/R }
267     */
268
269    /* ACLK_GDL/R L0: 200MHz */
270    {3, 1},
271    /* ACLK_GDL/R L1: 200MHz */
272    {3, 1},
273    /* ACLK_GDL/R L2: 160MHz */
274    {4, 1},
275    /* ACLK_GDL/R L3: 133MHz */
276    {5, 1},
277    /* ACLK_GDL/R L4: 100MHz */
278    {7, 1},
279};
280static unsigned int exynos4x12_clkdiv_sclkip[][3] = {
281    /*
282     * Clock divider value for following
283     * { DIVMFC, DIVJPEG, DIVFIMC0~3}
284     */
285
286    /* SCLK_MFC: 200MHz */
287    {3, 3, 4},
288    /* SCLK_MFC: 200MHz */
289    {3, 3, 4},
290    /* SCLK_MFC: 160MHz */
291    {4, 4, 5},
292    /* SCLK_MFC: 133MHz */
293    {5, 5, 5},
294    /* SCLK_MFC: 100MHz */
295    {7, 7, 7},
296};
297
298
299static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
300{
301    unsigned int index;
302    unsigned int tmp;
303
304    for (index = LV_0; index < EX4210_LV_NUM; index++)
305        if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk)
306            break;
307
308    if (index == EX4210_LV_NUM)
309        return -EINVAL;
310
311    /* Change Divider - DMC0 */
312    tmp = data->dmc_divtable[index];
313
314    __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
315
316    do {
317        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
318    } while (tmp & 0x11111111);
319
320    /* Change Divider - TOP */
321    tmp = data->top_divtable[index];
322
323    __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
324
325    do {
326        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
327    } while (tmp & 0x11111);
328
329    /* Change Divider - LEFTBUS */
330    tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
331
332    tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
333
334    tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
335                EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
336        (exynos4210_clkdiv_lr_bus[index][1] <<
337                EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
338
339    __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
340
341    do {
342        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
343    } while (tmp & 0x11);
344
345    /* Change Divider - RIGHTBUS */
346    tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
347
348    tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
349
350    tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
351                EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
352        (exynos4210_clkdiv_lr_bus[index][1] <<
353                EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
354
355    __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
356
357    do {
358        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
359    } while (tmp & 0x11);
360
361    return 0;
362}
363
364static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp)
365{
366    unsigned int index;
367    unsigned int tmp;
368
369    for (index = LV_0; index < EX4x12_LV_NUM; index++)
370        if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk)
371            break;
372
373    if (index == EX4x12_LV_NUM)
374        return -EINVAL;
375
376    /* Change Divider - DMC0 */
377    tmp = data->dmc_divtable[index];
378
379    __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
380
381    do {
382        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
383    } while (tmp & 0x11111111);
384
385    /* Change Divider - DMC1 */
386    tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
387
388    tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
389        EXYNOS4_CLKDIV_DMC1_C2C_MASK |
390        EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
391
392    tmp |= ((exynos4x12_clkdiv_dmc1[index][0] <<
393                EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
394        (exynos4x12_clkdiv_dmc1[index][1] <<
395                EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
396        (exynos4x12_clkdiv_dmc1[index][2] <<
397                EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
398
399    __raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
400
401    do {
402        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
403    } while (tmp & 0x111111);
404
405    /* Change Divider - TOP */
406    tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
407
408    tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
409        EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
410        EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
411        EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
412        EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
413
414    tmp |= ((exynos4x12_clkdiv_top[index][0] <<
415                EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
416        (exynos4x12_clkdiv_top[index][1] <<
417                EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
418        (exynos4x12_clkdiv_top[index][2] <<
419                EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
420        (exynos4x12_clkdiv_top[index][3] <<
421                EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
422        (exynos4x12_clkdiv_top[index][4] <<
423                EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
424
425    __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
426
427    do {
428        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
429    } while (tmp & 0x11111);
430
431    /* Change Divider - LEFTBUS */
432    tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
433
434    tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
435
436    tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
437                EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
438        (exynos4x12_clkdiv_lr_bus[index][1] <<
439                EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
440
441    __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
442
443    do {
444        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
445    } while (tmp & 0x11);
446
447    /* Change Divider - RIGHTBUS */
448    tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
449
450    tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
451
452    tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
453                EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
454        (exynos4x12_clkdiv_lr_bus[index][1] <<
455                EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
456
457    __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
458
459    do {
460        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
461    } while (tmp & 0x11);
462
463    /* Change Divider - MFC */
464    tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
465
466    tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
467
468    tmp |= ((exynos4x12_clkdiv_sclkip[index][0] <<
469                EXYNOS4_CLKDIV_MFC_SHIFT));
470
471    __raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
472
473    do {
474        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
475    } while (tmp & 0x1);
476
477    /* Change Divider - JPEG */
478    tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
479
480    tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
481
482    tmp |= ((exynos4x12_clkdiv_sclkip[index][1] <<
483                EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
484
485    __raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
486
487    do {
488        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
489    } while (tmp & 0x1);
490
491    /* Change Divider - FIMC0~3 */
492    tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
493
494    tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
495        EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
496
497    tmp |= ((exynos4x12_clkdiv_sclkip[index][2] <<
498                EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
499        (exynos4x12_clkdiv_sclkip[index][2] <<
500                EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
501        (exynos4x12_clkdiv_sclkip[index][2] <<
502                EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
503        (exynos4x12_clkdiv_sclkip[index][2] <<
504                EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
505
506    __raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
507
508    do {
509        tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
510    } while (tmp & 0x1111);
511
512    return 0;
513}
514
515
516static void busfreq_mon_reset(struct busfreq_data *data)
517{
518    unsigned int i;
519
520    for (i = 0; i < 2; i++) {
521        void __iomem *ppmu_base = data->dmc[i].hw_base;
522
523        /* Reset PPMU */
524        __raw_writel(0x8000000f, ppmu_base + 0xf010);
525        __raw_writel(0x8000000f, ppmu_base + 0xf050);
526        __raw_writel(0x6, ppmu_base + 0xf000);
527        __raw_writel(0x0, ppmu_base + 0xf100);
528
529        /* Set PPMU Event */
530        data->dmc[i].event = 0x6;
531        __raw_writel(((data->dmc[i].event << 12) | 0x1),
532                 ppmu_base + 0xfc);
533
534        /* Start PPMU */
535        __raw_writel(0x1, ppmu_base + 0xf000);
536    }
537}
538
539static void exynos4_read_ppmu(struct busfreq_data *data)
540{
541    int i, j;
542
543    for (i = 0; i < 2; i++) {
544        void __iomem *ppmu_base = data->dmc[i].hw_base;
545        u32 overflow;
546
547        /* Stop PPMU */
548        __raw_writel(0x0, ppmu_base + 0xf000);
549
550        /* Update local data from PPMU */
551        overflow = __raw_readl(ppmu_base + 0xf050);
552
553        data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100);
554        data->dmc[i].ccnt_overflow = overflow & (1 << 31);
555
556        for (j = 0; j < PPMU_PMNCNT_MAX; j++) {
557            data->dmc[i].count[j] = __raw_readl(
558                    ppmu_base + (0xf110 + (0x10 * j)));
559            data->dmc[i].count_overflow[j] = overflow & (1 << j);
560        }
561    }
562
563    busfreq_mon_reset(data);
564}
565
566static int exynos4x12_get_intspec(unsigned long mifclk)
567{
568    int i = 0;
569
570    while (exynos4x12_intclk_table[i].clk) {
571        if (exynos4x12_intclk_table[i].clk <= mifclk)
572            return i;
573        i++;
574    }
575
576    return -EINVAL;
577}
578
579static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
580                   struct opp *oldopp)
581{
582    int err = 0, tmp;
583    unsigned long volt = opp_get_voltage(opp);
584
585    switch (data->type) {
586    case TYPE_BUSF_EXYNOS4210:
587        /* OPP represents DMC clock + INT voltage */
588        err = regulator_set_voltage(data->vdd_int, volt,
589                        MAX_SAFEVOLT);
590        break;
591    case TYPE_BUSF_EXYNOS4x12:
592        /* OPP represents MIF clock + MIF voltage */
593        err = regulator_set_voltage(data->vdd_mif, volt,
594                        MAX_SAFEVOLT);
595        if (err)
596            break;
597
598        tmp = exynos4x12_get_intspec(opp_get_freq(opp));
599        if (tmp < 0) {
600            err = tmp;
601            regulator_set_voltage(data->vdd_mif,
602                          opp_get_voltage(oldopp),
603                          MAX_SAFEVOLT);
604            break;
605        }
606        err = regulator_set_voltage(data->vdd_int,
607                        exynos4x12_intclk_table[tmp].volt,
608                        MAX_SAFEVOLT);
609        /* Try to recover */
610        if (err)
611            regulator_set_voltage(data->vdd_mif,
612                          opp_get_voltage(oldopp),
613                          MAX_SAFEVOLT);
614        break;
615    default:
616        err = -EINVAL;
617    }
618
619    return err;
620}
621
622static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
623                  u32 flags)
624{
625    int err = 0;
626    struct platform_device *pdev = container_of(dev, struct platform_device,
627                            dev);
628    struct busfreq_data *data = platform_get_drvdata(pdev);
629    struct opp *opp = devfreq_recommended_opp(dev, _freq, flags);
630    unsigned long freq = opp_get_freq(opp);
631    unsigned long old_freq = opp_get_freq(data->curr_opp);
632
633    if (IS_ERR(opp))
634        return PTR_ERR(opp);
635
636    if (old_freq == freq)
637        return 0;
638
639    dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp));
640
641    mutex_lock(&data->lock);
642
643    if (data->disabled)
644        goto out;
645
646    if (old_freq < freq)
647        err = exynos4_bus_setvolt(data, opp, data->curr_opp);
648    if (err)
649        goto out;
650
651    if (old_freq != freq) {
652        switch (data->type) {
653        case TYPE_BUSF_EXYNOS4210:
654            err = exynos4210_set_busclk(data, opp);
655            break;
656        case TYPE_BUSF_EXYNOS4x12:
657            err = exynos4x12_set_busclk(data, opp);
658            break;
659        default:
660            err = -EINVAL;
661        }
662    }
663    if (err)
664        goto out;
665
666    if (old_freq > freq)
667        err = exynos4_bus_setvolt(data, opp, data->curr_opp);
668    if (err)
669        goto out;
670
671    data->curr_opp = opp;
672out:
673    mutex_unlock(&data->lock);
674    return err;
675}
676
677static int exynos4_get_busier_dmc(struct busfreq_data *data)
678{
679    u64 p0 = data->dmc[0].count[0];
680    u64 p1 = data->dmc[1].count[0];
681
682    p0 *= data->dmc[1].ccnt;
683    p1 *= data->dmc[0].ccnt;
684
685    if (data->dmc[1].ccnt == 0)
686        return 0;
687
688    if (p0 > p1)
689        return 0;
690    return 1;
691}
692
693static int exynos4_bus_get_dev_status(struct device *dev,
694                      struct devfreq_dev_status *stat)
695{
696    struct busfreq_data *data = dev_get_drvdata(dev);
697    int busier_dmc;
698    int cycles_x2 = 2; /* 2 x cycles */
699    void __iomem *addr;
700    u32 timing;
701    u32 memctrl;
702
703    exynos4_read_ppmu(data);
704    busier_dmc = exynos4_get_busier_dmc(data);
705    stat->current_frequency = opp_get_freq(data->curr_opp);
706
707    if (busier_dmc)
708        addr = S5P_VA_DMC1;
709    else
710        addr = S5P_VA_DMC0;
711
712    memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */
713    timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */
714
715    switch ((memctrl >> 8) & 0xf) {
716    case 0x4: /* DDR2 */
717        cycles_x2 = ((timing >> 16) & 0xf) * 2;
718        break;
719    case 0x5: /* LPDDR2 */
720    case 0x6: /* DDR3 */
721        cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf);
722        break;
723    default:
724        pr_err("%s: Unknown Memory Type(%d).\n", __func__,
725               (memctrl >> 8) & 0xf);
726        return -EINVAL;
727    }
728
729    /* Number of cycles spent on memory access */
730    stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2);
731    stat->busy_time *= 100 / BUS_SATURATION_RATIO;
732    stat->total_time = data->dmc[busier_dmc].ccnt;
733
734    /* If the counters have overflown, retry */
735    if (data->dmc[busier_dmc].ccnt_overflow ||
736        data->dmc[busier_dmc].count_overflow[0])
737        return -EAGAIN;
738
739    return 0;
740}
741
742static void exynos4_bus_exit(struct device *dev)
743{
744    struct busfreq_data *data = dev_get_drvdata(dev);
745
746    devfreq_unregister_opp_notifier(dev, data->devfreq);
747}
748
749static struct devfreq_dev_profile exynos4_devfreq_profile = {
750    .initial_freq = 400000,
751    .polling_ms = 50,
752    .target = exynos4_bus_target,
753    .get_dev_status = exynos4_bus_get_dev_status,
754    .exit = exynos4_bus_exit,
755};
756
757static int exynos4210_init_tables(struct busfreq_data *data)
758{
759    u32 tmp;
760    int mgrp;
761    int i, err = 0;
762
763    tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
764    for (i = LV_0; i < EX4210_LV_NUM; i++) {
765        tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
766            EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
767            EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
768            EXYNOS4_CLKDIV_DMC0_DMC_MASK |
769            EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
770            EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
771            EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
772            EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
773
774        tmp |= ((exynos4210_clkdiv_dmc0[i][0] <<
775                    EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
776            (exynos4210_clkdiv_dmc0[i][1] <<
777                    EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
778            (exynos4210_clkdiv_dmc0[i][2] <<
779                    EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
780            (exynos4210_clkdiv_dmc0[i][3] <<
781                    EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
782            (exynos4210_clkdiv_dmc0[i][4] <<
783                    EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
784            (exynos4210_clkdiv_dmc0[i][5] <<
785                    EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
786            (exynos4210_clkdiv_dmc0[i][6] <<
787                    EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
788            (exynos4210_clkdiv_dmc0[i][7] <<
789                    EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
790
791        data->dmc_divtable[i] = tmp;
792    }
793
794    tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
795    for (i = LV_0; i < EX4210_LV_NUM; i++) {
796        tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
797            EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
798            EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
799            EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
800            EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
801
802        tmp |= ((exynos4210_clkdiv_top[i][0] <<
803                    EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
804            (exynos4210_clkdiv_top[i][1] <<
805                    EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
806            (exynos4210_clkdiv_top[i][2] <<
807                    EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
808            (exynos4210_clkdiv_top[i][3] <<
809                    EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
810            (exynos4210_clkdiv_top[i][4] <<
811                    EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
812
813        data->top_divtable[i] = tmp;
814    }
815
816#ifdef CONFIG_EXYNOS_ASV
817    tmp = exynos4_result_of_asv;
818#else
819    tmp = 0; /* Max voltages for the reliability of the unknown */
820#endif
821
822    pr_debug("ASV Group of Exynos4 is %d\n", tmp);
823    /* Use merged grouping for voltage */
824    switch (tmp) {
825    case 0:
826        mgrp = 0;
827        break;
828    case 1:
829    case 2:
830        mgrp = 1;
831        break;
832    case 3:
833    case 4:
834        mgrp = 2;
835        break;
836    case 5:
837    case 6:
838        mgrp = 3;
839        break;
840    case 7:
841        mgrp = 4;
842        break;
843    default:
844        pr_warn("Unknown ASV Group. Use max voltage.\n");
845        mgrp = 0;
846    }
847
848    for (i = LV_0; i < EX4210_LV_NUM; i++)
849        exynos4210_busclk_table[i].volt = exynos4210_asv_volt[mgrp][i];
850
851    for (i = LV_0; i < EX4210_LV_NUM; i++) {
852        err = opp_add(data->dev, exynos4210_busclk_table[i].clk,
853                  exynos4210_busclk_table[i].volt);
854        if (err) {
855            dev_err(data->dev, "Cannot add opp entries.\n");
856            return err;
857        }
858    }
859
860
861    return 0;
862}
863
864static int exynos4x12_init_tables(struct busfreq_data *data)
865{
866    unsigned int i;
867    unsigned int tmp;
868    int ret;
869
870    /* Enable pause function for DREX2 DVFS */
871    tmp = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
872    tmp |= EXYNOS4_DMC_PAUSE_ENABLE;
873    __raw_writel(tmp, EXYNOS4_DMC_PAUSE_CTRL);
874
875    tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
876
877    for (i = 0; i < EX4x12_LV_NUM; i++) {
878        tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
879            EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
880            EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
881            EXYNOS4_CLKDIV_DMC0_DMC_MASK |
882            EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
883            EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
884
885        tmp |= ((exynos4x12_clkdiv_dmc0[i][0] <<
886                    EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
887            (exynos4x12_clkdiv_dmc0[i][1] <<
888                    EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
889            (exynos4x12_clkdiv_dmc0[i][2] <<
890                    EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
891            (exynos4x12_clkdiv_dmc0[i][3] <<
892                    EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
893            (exynos4x12_clkdiv_dmc0[i][4] <<
894                    EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
895            (exynos4x12_clkdiv_dmc0[i][5] <<
896                    EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
897
898        data->dmc_divtable[i] = tmp;
899    }
900
901#ifdef CONFIG_EXYNOS_ASV
902    tmp = exynos4_result_of_asv;
903#else
904    tmp = 0; /* Max voltages for the reliability of the unknown */
905#endif
906
907    if (tmp > 8)
908        tmp = 0;
909    pr_debug("ASV Group of Exynos4x12 is %d\n", tmp);
910
911    for (i = 0; i < EX4x12_LV_NUM; i++) {
912        exynos4x12_mifclk_table[i].volt =
913            exynos4x12_mif_step_50[tmp][i];
914        exynos4x12_intclk_table[i].volt =
915            exynos4x12_int_volt[tmp][i];
916    }
917
918    for (i = 0; i < EX4x12_LV_NUM; i++) {
919        ret = opp_add(data->dev, exynos4x12_mifclk_table[i].clk,
920                  exynos4x12_mifclk_table[i].volt);
921        if (ret) {
922            dev_err(data->dev, "Fail to add opp entries.\n");
923            return ret;
924        }
925    }
926
927    return 0;
928}
929
930static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
931        unsigned long event, void *ptr)
932{
933    struct busfreq_data *data = container_of(this, struct busfreq_data,
934                         pm_notifier);
935    struct opp *opp;
936    unsigned long maxfreq = ULONG_MAX;
937    int err = 0;
938
939    switch (event) {
940    case PM_SUSPEND_PREPARE:
941        /* Set Fastest and Deactivate DVFS */
942        mutex_lock(&data->lock);
943
944        data->disabled = true;
945
946        opp = opp_find_freq_floor(data->dev, &maxfreq);
947
948        err = exynos4_bus_setvolt(data, opp, data->curr_opp);
949        if (err)
950            goto unlock;
951
952        switch (data->type) {
953        case TYPE_BUSF_EXYNOS4210:
954            err = exynos4210_set_busclk(data, opp);
955            break;
956        case TYPE_BUSF_EXYNOS4x12:
957            err = exynos4x12_set_busclk(data, opp);
958            break;
959        default:
960            err = -EINVAL;
961        }
962        if (err)
963            goto unlock;
964
965        data->curr_opp = opp;
966unlock:
967        mutex_unlock(&data->lock);
968        if (err)
969            return err;
970        return NOTIFY_OK;
971    case PM_POST_RESTORE:
972    case PM_POST_SUSPEND:
973        /* Reactivate */
974        mutex_lock(&data->lock);
975        data->disabled = false;
976        mutex_unlock(&data->lock);
977        return NOTIFY_OK;
978    }
979
980    return NOTIFY_DONE;
981}
982
983static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
984{
985    struct busfreq_data *data;
986    struct opp *opp;
987    struct device *dev = &pdev->dev;
988    int err = 0;
989
990    data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
991    if (data == NULL) {
992        dev_err(dev, "Cannot allocate memory.\n");
993        return -ENOMEM;
994    }
995
996    data->type = pdev->id_entry->driver_data;
997    data->dmc[0].hw_base = S5P_VA_DMC0;
998    data->dmc[1].hw_base = S5P_VA_DMC1;
999    data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
1000    data->dev = dev;
1001    mutex_init(&data->lock);
1002
1003    switch (data->type) {
1004    case TYPE_BUSF_EXYNOS4210:
1005        err = exynos4210_init_tables(data);
1006        break;
1007    case TYPE_BUSF_EXYNOS4x12:
1008        err = exynos4x12_init_tables(data);
1009        break;
1010    default:
1011        dev_err(dev, "Cannot determine the device id %d\n", data->type);
1012        err = -EINVAL;
1013    }
1014    if (err)
1015        goto err_regulator;
1016
1017    data->vdd_int = regulator_get(dev, "vdd_int");
1018    if (IS_ERR(data->vdd_int)) {
1019        dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
1020        err = PTR_ERR(data->vdd_int);
1021        goto err_regulator;
1022    }
1023    if (data->type == TYPE_BUSF_EXYNOS4x12) {
1024        data->vdd_mif = regulator_get(dev, "vdd_mif");
1025        if (IS_ERR(data->vdd_mif)) {
1026            dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
1027            err = PTR_ERR(data->vdd_mif);
1028            regulator_put(data->vdd_int);
1029            goto err_regulator;
1030
1031        }
1032    }
1033
1034    opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
1035    if (IS_ERR(opp)) {
1036        dev_err(dev, "Invalid initial frequency %lu kHz.\n",
1037               exynos4_devfreq_profile.initial_freq);
1038        err = PTR_ERR(opp);
1039        goto err_opp_add;
1040    }
1041    data->curr_opp = opp;
1042
1043    platform_set_drvdata(pdev, data);
1044
1045    busfreq_mon_reset(data);
1046
1047    data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
1048                       &devfreq_simple_ondemand, NULL);
1049    if (IS_ERR(data->devfreq)) {
1050        err = PTR_ERR(data->devfreq);
1051        goto err_opp_add;
1052    }
1053
1054    devfreq_register_opp_notifier(dev, data->devfreq);
1055
1056    err = register_pm_notifier(&data->pm_notifier);
1057    if (err) {
1058        dev_err(dev, "Failed to setup pm notifier\n");
1059        goto err_devfreq_add;
1060    }
1061
1062    return 0;
1063err_devfreq_add:
1064    devfreq_remove_device(data->devfreq);
1065err_opp_add:
1066    if (data->vdd_mif)
1067        regulator_put(data->vdd_mif);
1068    regulator_put(data->vdd_int);
1069err_regulator:
1070    kfree(data);
1071    return err;
1072}
1073
1074static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
1075{
1076    struct busfreq_data *data = platform_get_drvdata(pdev);
1077
1078    unregister_pm_notifier(&data->pm_notifier);
1079    devfreq_remove_device(data->devfreq);
1080    regulator_put(data->vdd_int);
1081    if (data->vdd_mif)
1082        regulator_put(data->vdd_mif);
1083    kfree(data);
1084
1085    return 0;
1086}
1087
1088static int exynos4_busfreq_resume(struct device *dev)
1089{
1090    struct busfreq_data *data = dev_get_drvdata(dev);
1091
1092    busfreq_mon_reset(data);
1093    return 0;
1094}
1095
1096static const struct dev_pm_ops exynos4_busfreq_pm = {
1097    .resume = exynos4_busfreq_resume,
1098};
1099
1100static const struct platform_device_id exynos4_busfreq_id[] = {
1101    { "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 },
1102    { "exynos4412-busfreq", TYPE_BUSF_EXYNOS4x12 },
1103    { "exynos4212-busfreq", TYPE_BUSF_EXYNOS4x12 },
1104    { },
1105};
1106
1107static struct platform_driver exynos4_busfreq_driver = {
1108    .probe = exynos4_busfreq_probe,
1109    .remove = __devexit_p(exynos4_busfreq_remove),
1110    .id_table = exynos4_busfreq_id,
1111    .driver = {
1112        .name = "exynos4-busfreq",
1113        .owner = THIS_MODULE,
1114        .pm = &exynos4_busfreq_pm,
1115    },
1116};
1117
1118static int __init exynos4_busfreq_init(void)
1119{
1120    return platform_driver_register(&exynos4_busfreq_driver);
1121}
1122late_initcall(exynos4_busfreq_init);
1123
1124static void __exit exynos4_busfreq_exit(void)
1125{
1126    platform_driver_unregister(&exynos4_busfreq_driver);
1127}
1128module_exit(exynos4_busfreq_exit);
1129
1130MODULE_LICENSE("GPL");
1131MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework");
1132MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1133

Archive Download this file



interactive