1 // SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
2 /*
3  * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <dfu.h>
7 #include <dm.h>
8 #include <misc.h>
9 #include <asm/arch/stm32prog.h>
10 #include <power/stpmic1.h>
11 
dfu_otp_read(u64 offset,u8 * buffer,long * size)12 static int dfu_otp_read(u64 offset, u8 *buffer, long *size)
13 {
14 	struct udevice *dev;
15 	int ret;
16 
17 	ret = uclass_get_device_by_driver(UCLASS_MISC,
18 					  DM_DRIVER_GET(stm32mp_bsec),
19 					  &dev);
20 	if (ret)
21 		return ret;
22 
23 	ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size);
24 	if (ret >= 0) {
25 		*size = ret;
26 		ret = 0;
27 	}
28 
29 	return 0;
30 }
31 
dfu_pmic_read(u64 offset,u8 * buffer,long * size)32 static int dfu_pmic_read(u64 offset, u8 *buffer, long *size)
33 {
34 	int ret;
35 	struct udevice *dev;
36 
37 	if (!IS_ENABLED(CONFIG_PMIC_STPMIC1)) {
38 		log_err("PMIC update not supported");
39 		return -EOPNOTSUPP;
40 	}
41 
42 	ret = uclass_get_device_by_driver(UCLASS_MISC,
43 					  DM_DRIVER_GET(stpmic1_nvm),
44 					  &dev);
45 	if (ret)
46 		return ret;
47 
48 	ret = misc_read(dev, 0xF8 + offset, buffer, *size);
49 	if (ret >= 0) {
50 		*size = ret;
51 		ret = 0;
52 	}
53 	if (ret == -EACCES) {
54 		*size = 0;
55 		ret = 0;
56 	}
57 
58 	return ret;
59 }
60 
dfu_read_medium_virt(struct dfu_entity * dfu,u64 offset,void * buf,long * len)61 int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
62 			 void *buf, long *len)
63 {
64 	switch (dfu->data.virt.dev_num) {
65 	case 0x0:
66 		return dfu_otp_read(offset, buf, len);
67 	case 0x1:
68 		return dfu_pmic_read(offset, buf, len);
69 	}
70 
71 	if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) &&
72 	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
73 		return stm32prog_read_medium_virt(dfu, offset, buf, len);
74 
75 	*len = 0;
76 	return 0;
77 }
78 
dfu_write_medium_virt(struct dfu_entity * dfu,u64 offset,void * buf,long * len)79 int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
80 			  void *buf, long *len)
81 {
82 	if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) &&
83 	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
84 		return stm32prog_write_medium_virt(dfu, offset, buf, len);
85 
86 	return -EOPNOTSUPP;
87 }
88 
dfu_get_medium_size_virt(struct dfu_entity * dfu,u64 * size)89 int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
90 {
91 	if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) &&
92 	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
93 		return stm32prog_get_medium_size_virt(dfu, size);
94 
95 	*size = SZ_1K;
96 
97 	return 0;
98 }
99