1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/cache.h>
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/device.h>
9 #include <soc/dp-core.h>
15 static unsigned int cpu_id
;
16 static unsigned int cpu_rev
;
18 static void set_cpu_id(void)
20 cpu_id
= read32((void *)EXYNOS5_PRO_ID
);
21 cpu_id
= (0xC000 | ((cpu_id
& 0x00FFF000) >> 12));
24 * 0xC200: EXYNOS4210 EVT0
25 * 0xC210: EXYNOS4210 EVT1
27 if (cpu_id
== 0xC200) {
30 } else if (cpu_id
== 0xC210) {
35 /* we distinguish a display port device from a raw graphics device
36 * because there are dramatic differences in startup depending on
37 * graphics usage. To make startup fast and easier to understand and
38 * debug we explicitly name this common case. The alternate approach,
39 * involving lots of machine and callbacks, is hard to debug and
42 static void exynos_displayport_init(struct device
*dev
, u32 lcdbase
,
43 unsigned long fb_size
)
45 struct soc_samsung_exynos5250_config
*conf
= dev
->chip_info
;
46 /* put these on the stack. If, at some point, we want to move
47 * this code to a pre-ram stage, it will be much easier.
49 struct exynos5_fimd_panel panel
;
50 memset(&panel
, 0, sizeof(panel
));
52 panel
.is_dp
= 1; /* Display I/F is eDP */
53 /* while it is true that we did a memset to zero,
54 * we leave some 'set to zero' entries here to make
55 * it clear what's going on. Graphics is confusing.
60 panel
.clkval_f
= conf
->clkval_f
;
61 panel
.upper_margin
= conf
->upper_margin
;
62 panel
.lower_margin
= conf
->lower_margin
;
63 panel
.vsync
= conf
->vsync
;
64 panel
.left_margin
= conf
->left_margin
;
65 panel
.right_margin
= conf
->right_margin
;
66 panel
.hsync
= conf
->hsync
;
67 panel
.xres
= conf
->xres
;
68 panel
.yres
= conf
->yres
;
70 printk(BIOS_SPEW
, "LCD framebuffer @%p\n", (void *)(lcdbase
));
71 memset((void *)lcdbase
, 0, fb_size
); /* clear the framebuffer */
74 * We need to clean and invalidate the framebuffer region and disable
75 * caching as well. We assume that our dcache <--> memory address
76 * space is identity-mapped in 1MB chunks, so align accordingly.
78 * Note: We may want to do something clever to ensure the framebuffer
79 * region is aligned such that we don't change dcache policy for other
80 * stuff inadvertently.
82 uint32_t lower
= ALIGN_DOWN(lcdbase
, MiB
);
83 uint32_t upper
= ALIGN_UP(lcdbase
+ fb_size
, MiB
);
85 dcache_clean_invalidate_by_mva((void *)lower
, upper
- lower
);
86 mmu_config_range(lower
/ MiB
, (upper
- lower
) / MiB
, DCACHE_OFF
);
88 printk(BIOS_DEBUG
, "Initializing Exynos LCD.\n");
90 lcd_ctrl_init(fb_size
, &panel
, (void *)lcdbase
);
93 static void cpu_enable(struct device
*dev
)
95 unsigned long fb_size
= FB_SIZE_KB
* KiB
;
96 u32 lcdbase
= get_fb_base_kb() * KiB
;
98 exynos_displayport_init(dev
, lcdbase
, fb_size
);
103 static void cpu_read_resources(struct device
*dev
)
105 unsigned long fb_size
= FB_SIZE_KB
* KiB
;
106 u32 lcdbase
= get_fb_base_kb() * KiB
;
108 ram_range(dev
, 0, RAM_BASE_KB
* KiB
, (RAM_SIZE_KB
- FB_SIZE_KB
) * KiB
);
109 mmio_range(dev
, 1, lcdbase
, fb_size
);
112 static void cpu_init(struct device
*dev
)
114 printk(BIOS_INFO
, "CPU: S5P%X @ %ldMHz\n",
115 cpu_id
, get_arm_clk() / (1024*1024));
118 static struct device_operations cpu_ops
= {
119 .read_resources
= cpu_read_resources
,
120 .set_resources
= noop_set_resources
,
121 .enable_resources
= cpu_enable
,
125 static void enable_exynos5250_dev(struct device
*dev
)
130 struct chip_operations soc_samsung_exynos5250_ops
= {
131 .name
= "SOC Samsung Exynos 5250",
132 .enable_dev
= enable_exynos5250_dev
,
135 void exynos5250_config_l2_cache(void)
140 * Bit 9 - L2 tag RAM setup (1 cycle)
141 * Bits 8:6 - L2 tag RAM latency (3 cycles)
142 * Bit 5 - L2 data RAM setup (1 cycle)
143 * Bits 2:0 - L2 data RAM latency (3 cycles)
145 val
= (1 << 9) | (0x2 << 6) | (1 << 5) | (0x2);