1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * SMS/SDRC (SDRAM controller) common code for OMAP2/3 |
4 | * |
5 | * Copyright (C) 2005, 2008 Texas Instruments Inc. |
6 | * Copyright (C) 2005, 2008 Nokia Corporation |
7 | * |
8 | * Tony Lindgren <tony@atomide.com> |
9 | * Paul Walmsley |
10 | * Richard Woodruff <r-woodruff2@ti.com> |
11 | */ |
12 | #undef DEBUG |
13 | |
14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> |
16 | #include <linux/device.h> |
17 | #include <linux/list.h> |
18 | #include <linux/errno.h> |
19 | #include <linux/delay.h> |
20 | #include <linux/clk.h> |
21 | #include <linux/io.h> |
22 | |
23 | #include "common.h" |
24 | #include "clock.h" |
25 | #include "sdrc.h" |
26 | |
27 | static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; |
28 | |
29 | void __iomem *omap2_sdrc_base; |
30 | void __iomem *omap2_sms_base; |
31 | |
32 | struct omap2_sms_regs { |
33 | u32 sms_sysconfig; |
34 | }; |
35 | |
36 | static struct omap2_sms_regs sms_context; |
37 | |
38 | /* SDRC_POWER register bits */ |
39 | #define SDRC_POWER_EXTCLKDIS_SHIFT 3 |
40 | #define SDRC_POWER_PWDENA_SHIFT 2 |
41 | #define SDRC_POWER_PAGEPOLICY_SHIFT 0 |
42 | |
43 | /** |
44 | * omap2_sms_save_context - Save SMS registers |
45 | * |
46 | * Save SMS registers that need to be restored after off mode. |
47 | */ |
48 | static void omap2_sms_save_context(void) |
49 | { |
50 | sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); |
51 | } |
52 | |
53 | /** |
54 | * omap2_sms_restore_context - Restore SMS registers |
55 | * |
56 | * Restore SMS registers that need to be Restored after off mode. |
57 | */ |
58 | void omap2_sms_restore_context(void) |
59 | { |
60 | sms_write_reg(val: sms_context.sms_sysconfig, SMS_SYSCONFIG); |
61 | } |
62 | |
63 | void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms) |
64 | { |
65 | omap2_sdrc_base = sdrc; |
66 | omap2_sms_base = sms; |
67 | } |
68 | |
69 | /** |
70 | * omap2_sdrc_init - initialize SMS, SDRC devices on boot |
71 | * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params |
72 | * Support for 2 chip selects timings |
73 | * |
74 | * Turn on smart idle modes for SDRAM scheduler and controller. |
75 | * Program a known-good configuration for the SDRC to deal with buggy |
76 | * bootloaders. |
77 | */ |
78 | void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, |
79 | struct omap_sdrc_params *sdrc_cs1) |
80 | { |
81 | u32 l; |
82 | |
83 | l = sms_read_reg(SMS_SYSCONFIG); |
84 | l &= ~(0x3 << 3); |
85 | l |= (0x2 << 3); |
86 | sms_write_reg(val: l, SMS_SYSCONFIG); |
87 | |
88 | l = sdrc_read_reg(SDRC_SYSCONFIG); |
89 | l &= ~(0x3 << 3); |
90 | l |= (0x2 << 3); |
91 | sdrc_write_reg(val: l, SDRC_SYSCONFIG); |
92 | |
93 | sdrc_init_params_cs0 = sdrc_cs0; |
94 | sdrc_init_params_cs1 = sdrc_cs1; |
95 | |
96 | /* XXX Enable SRFRONIDLEREQ here also? */ |
97 | /* |
98 | * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA |
99 | * can cause random memory corruption |
100 | */ |
101 | l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | |
102 | (1 << SDRC_POWER_PAGEPOLICY_SHIFT); |
103 | sdrc_write_reg(val: l, SDRC_POWER); |
104 | omap2_sms_save_context(); |
105 | } |
106 | |