coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
cpu.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/cache.h>
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/device.h>
8 #include <soc/dp.h>
9 #include <soc/fimd.h>
10 #include <soc/cpu.h>
11 #include <soc/clk.h>
12 #include <string.h>
13 
14 #include "chip.h"
15 
16 static unsigned int cpu_id;
17 static unsigned int cpu_rev;
18 
19 static void set_cpu_id(void)
20 {
21  u32 pro_id = (read32((void *)EXYNOS5_PRO_ID) & 0x00FFF000) >> 12;
22 
23  switch (pro_id) {
24  case 0x200:
25  /* Exynos4210 EVT0 */
26  cpu_id = 0x4210;
27  cpu_rev = 0;
28  break;
29  case 0x210:
30  /* Exynos4210 EVT1 */
31  cpu_id = 0x4210;
32  break;
33  case 0x412:
34  /* Exynos4412 */
35  cpu_id = 0x4412;
36  break;
37  case 0x520:
38  /* Exynos5250 */
39  cpu_id = 0x5250;
40  break;
41  case 0x420:
42  /* Exynos5420 */
43  cpu_id = 0x5420;
44  break;
45  }
46 }
47 
48 /* we distinguish a display port device from a raw graphics device
49  * because there are dramatic differences in startup depending on
50  * graphics usage. To make startup fast and easier to understand and
51  * debug we explicitly name this common case. The alternate approach,
52  * involving lots of machine and callbacks, is hard to debug and
53  * verify.
54  */
55 static void exynos_displayport_init(struct device *dev, u32 lcdbase,
56  unsigned long fb_size)
57 {
58  struct soc_samsung_exynos5420_config *conf = dev->chip_info;
59  /* put these on the stack. If, at some point, we want to move
60  * this code to a pre-ram stage, it will be much easier.
61  */
62  struct exynos5_fimd_panel panel;
63  memset(&panel, 0, sizeof(panel));
64 
65  panel.is_dp = 1; /* Display I/F is eDP */
66  /* while it is true that we did a memset to zero,
67  * we leave some 'set to zero' entries here to make
68  * it clear what's going on. Graphics is confusing.
69  */
70  panel.is_mipi = 0;
71  panel.fixvclk = 0;
72  panel.ivclk = 0;
73  panel.clkval_f = conf->clkval_f;
74  panel.upper_margin = conf->upper_margin;
75  panel.lower_margin = conf->lower_margin;
76  panel.vsync = conf->vsync;
77  panel.left_margin = conf->left_margin;
78  panel.right_margin = conf->right_margin;
79  panel.hsync = conf->hsync;
80  panel.xres = conf->xres;
81  panel.yres = conf->yres;
82 
83  printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase));
84  memset((void *)lcdbase, 0, fb_size); /* clear the framebuffer */
85 
86  /*
87  * We need to clean and invalidate the framebuffer region and disable
88  * caching as well. We assume that our dcache <--> memory address
89  * space is identity-mapped in 1MB chunks, so align accordingly.
90  *
91  * Note: We may want to do something clever to ensure the framebuffer
92  * region is aligned such that we don't change dcache policy for other
93  * stuff inadvertently.
94  */
95  uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
96  uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
97 
98  dcache_clean_invalidate_by_mva((void *)lower, upper - lower);
99  mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF);
100 }
101 
102 static void tps65090_thru_ec_fet_disable(int index)
103 {
104  uint8_t value = 0;
105 
106  if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
108  "Error sending i2c pass through command to EC.\n");
109  return;
110  }
111 }
112 
113 static void cpu_enable(struct device *dev)
114 {
115  unsigned long fb_size = FB_SIZE_KB * KiB;
116  u32 lcdbase = get_fb_base_kb() * KiB;
117 
118  /*
119  * Disable LCD FETs before we do anything with the display.
120  * FIXME(dhendrix): This is a gross hack and should be done
121  * elsewhere (romstage?).
122  */
125 
126  exynos_displayport_init(dev, lcdbase, fb_size);
127 
128  set_cpu_id();
129 }
130 
131 static void cpu_read_resources(struct device *dev)
132 {
133  unsigned long fb_size = FB_SIZE_KB * KiB;
134  u32 lcdbase = get_fb_base_kb() * KiB;
135 
137  mmio_resource(dev, 1, lcdbase / KiB, DIV_ROUND_UP(fb_size, KiB));
138 }
139 
140 static void cpu_init(struct device *dev)
141 {
142  printk(BIOS_INFO, "CPU: S5P%X @ %ldMHz\n",
143  cpu_id, get_arm_clk() / 1000000);
144 }
145 
146 static struct device_operations cpu_ops = {
148  .set_resources = noop_set_resources,
149  .enable_resources = cpu_enable,
150  .init = cpu_init,
151 };
152 
153 static void enable_exynos5420_dev(struct device *dev)
154 {
155  dev->ops = &cpu_ops;
156 }
157 
159  CHIP_NAME("SOC Samsung Exynos 5420")
160  .enable_dev = enable_exynos5420_dev,
161 };
pte_t value
Definition: mmu.c:91
void mmu_config_range(u32 start_mb, u32 size_mb, enum dcache_policy policy)
Definition: mmu.c:221
static uint32_t read32(const void *addr)
Definition: mmio.h:22
@ DCACHE_OFF
Definition: cache.h:363
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define ALIGN_DOWN(x, a)
Definition: helpers.h:18
#define MiB
Definition: helpers.h:76
#define KiB
Definition: helpers.h:75
#define ALIGN_UP(x, a)
Definition: helpers.h:17
#define DIV_ROUND_UP(x, y)
Definition: helpers.h:60
#define printk(level,...)
Definition: stdlib.h:16
int google_chromeec_i2c_xfer(uint8_t chip, uint8_t addr, int alen, uint8_t *buffer, int len, int is_read)
Definition: ec.c:1030
#define CHIP_NAME(X)
Definition: device.h:32
static void noop_set_resources(struct device *dev)
Definition: device.h:74
#define ram_resource(dev, idx, basek, sizek)
Definition: device.h:321
#define mmio_resource(dev, idx, basek, sizek)
Definition: device.h:334
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
unsigned long get_arm_clk(void)
Definition: clock.c:315
#define RAM_BASE_KB
Definition: cpu.h:63
#define RAM_SIZE_KB
Definition: cpu.h:64
static u32 get_fb_base_kb(void)
Definition: cpu.h:66
#define EXYNOS5_PRO_ID
Definition: cpu.h:11
#define FB_SIZE_KB
Definition: cpu.h:62
static void cpu_enable(struct device *dev)
Definition: cpu.c:113
static void tps65090_thru_ec_fet_disable(int index)
Definition: cpu.c:102
static unsigned int cpu_id
Definition: cpu.c:16
static void enable_exynos5420_dev(struct device *dev)
Definition: cpu.c:153
static void cpu_init(struct device *dev)
Definition: cpu.c:140
static void cpu_read_resources(struct device *dev)
Definition: cpu.c:131
static unsigned int cpu_rev
Definition: cpu.c:17
static struct device_operations cpu_ops
Definition: cpu.c:146
static void set_cpu_id(void)
Definition: cpu.c:19
struct chip_operations soc_samsung_exynos5420_ops
Definition: cpu.c:158
static void exynos_displayport_init(struct device *dev, u32 lcdbase, unsigned long fb_size)
Definition: cpu.c:55
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned char uint8_t
Definition: stdint.h:8
#define dcache_clean_invalidate_by_mva(addr, len)
Definition: storage.h:18
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int is_mipi
Definition: fimd.h:63
unsigned int right_margin
Definition: fimd.h:78
unsigned int left_margin
Definition: fimd.h:77
unsigned int upper_margin
Definition: fimd.h:74
unsigned int clkval_f
Definition: fimd.h:72
unsigned int lower_margin
Definition: fimd.h:75
unsigned int yres
Definition: fimd.h:81
unsigned int hsync
Definition: fimd.h:79
unsigned int ivclk
Definition: fimd.h:71
unsigned int is_dp
Definition: fimd.h:62
unsigned int vsync
Definition: fimd.h:76
unsigned int xres
Definition: fimd.h:80
unsigned int fixvclk
Definition: fimd.h:64