blob: 99ea21ce15f55be678e921b2b0baea9869c3a126 [file] [log] [blame]
Patrick Delaunaycf073432020-03-18 09:22:45 +01001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
6#include <common.h>
7#include <dfu.h>
8#include <env.h>
9#include <memalign.h>
10#include <misc.h>
11#include <mtd.h>
12#include <mtd_node.h>
13
14#define DFU_ALT_BUF_LEN SZ_1K
15
16static void board_get_alt_info(const char *dev, char *buff)
17{
18 char var_name[32] = "dfu_alt_info_";
19 int ret;
20
21 ALLOC_CACHE_ALIGN_BUFFER(char, tmp_alt, DFU_ALT_BUF_LEN);
22
23 /* name of env variable to read = dfu_alt_info_<dev> */
24 strcat(var_name, dev);
25 ret = env_get_f(var_name, tmp_alt, DFU_ALT_BUF_LEN);
26 if (ret) {
27 if (buff[0] != '\0')
28 strcat(buff, "&");
29 strncat(buff, tmp_alt, DFU_ALT_BUF_LEN);
30 }
31}
32
33void set_dfu_alt_info(char *interface, char *devstr)
34{
35 struct udevice *dev;
36 struct mtd_info *mtd;
37
38 ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
39
40 if (env_get("dfu_alt_info"))
41 return;
42
43 memset(buf, 0, sizeof(buf));
44
45 /* probe all MTD devices */
46 mtd_probe_devices();
47
48 board_get_alt_info("ram", buf);
49
50 if (!uclass_get_device(UCLASS_MMC, 0, &dev))
51 board_get_alt_info("mmc0", buf);
52
53 if (!uclass_get_device(UCLASS_MMC, 1, &dev))
54 board_get_alt_info("mmc1", buf);
55
56 if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
57 board_get_alt_info("nor0", buf);
58
59 mtd = get_mtd_device_nm("nand0");
60 if (!IS_ERR_OR_NULL(mtd))
61 board_get_alt_info("nand0", buf);
62
63 mtd = get_mtd_device_nm("spi-nand0");
64 if (!IS_ERR_OR_NULL(mtd))
65 board_get_alt_info("spi-nand0", buf);
66
67#ifdef CONFIG_DFU_VIRT
68 strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN);
69
70 if (IS_ENABLED(CONFIG_PMIC_STPMIC1))
71 strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN);
72#endif
73
74 env_set("dfu_alt_info", buf);
75 puts("DFU alt info setting: done\n");
76}
77
78#if CONFIG_IS_ENABLED(DFU_VIRT)
79#include <dfu.h>
80#include <power/stpmic1.h>
81
82static int dfu_otp_read(u64 offset, u8 *buffer, long *size)
83{
84 struct udevice *dev;
85 int ret;
86
87 ret = uclass_get_device_by_driver(UCLASS_MISC,
88 DM_GET_DRIVER(stm32mp_bsec),
89 &dev);
90 if (ret)
91 return ret;
92
93 ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size);
94 if (ret >= 0) {
95 *size = ret;
96 ret = 0;
97 }
98
99 return 0;
100}
101
102static int dfu_pmic_read(u64 offset, u8 *buffer, long *size)
103{
104 int ret;
105#ifdef CONFIG_PMIC_STPMIC1
106 struct udevice *dev;
107
108 ret = uclass_get_device_by_driver(UCLASS_MISC,
109 DM_GET_DRIVER(stpmic1_nvm),
110 &dev);
111 if (ret)
112 return ret;
113
114 ret = misc_read(dev, 0xF8 + offset, buffer, *size);
115 if (ret >= 0) {
116 *size = ret;
117 ret = 0;
118 }
119 if (ret == -EACCES) {
120 *size = 0;
121 ret = 0;
122 }
123#else
124 pr_err("PMIC update not supported");
125 ret = -EOPNOTSUPP;
126#endif
127
128 return ret;
129}
130
131int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
132 void *buf, long *len)
133{
134 switch (dfu->data.virt.dev_num) {
135 case 0x0:
136 return dfu_otp_read(offset, buf, len);
137 case 0x1:
138 return dfu_pmic_read(offset, buf, len);
139 }
140 *len = 0;
141 return 0;
142}
143
144int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
145{
146 *size = SZ_1K;
147
148 return 0;
149}
150
151#endif