xref: /openbmc/u-boot/board/freescale/common/zm7300.c (revision 63a7578e)
14150f242SShaveta Leekha /*
24150f242SShaveta Leekha  * Copyright 2013 Freescale Semiconductor, Inc.
34150f242SShaveta Leekha  *
44150f242SShaveta Leekha  * SPDX-License-Identifier:     GPL-2.0+
54150f242SShaveta Leekha  */
64150f242SShaveta Leekha 
74150f242SShaveta Leekha /* Power-One ZM7300 DPM */
84150f242SShaveta Leekha #include "zm7300.h"
94150f242SShaveta Leekha 
104150f242SShaveta Leekha #define DPM_WP 0x96
114150f242SShaveta Leekha #define WRP_OPCODE 0x01
124150f242SShaveta Leekha #define WRM_OPCODE 0x02
134150f242SShaveta Leekha #define RRP_OPCODE 0x11
144150f242SShaveta Leekha 
154150f242SShaveta Leekha #define DPM_SUCCESS 0x01
164150f242SShaveta Leekha #define DPM_EXEC_FAIL 0x00
174150f242SShaveta Leekha 
184150f242SShaveta Leekha static const uint16_t hex_to_1_10mv[] = {
194150f242SShaveta Leekha 	5000,
204150f242SShaveta Leekha 	5125,
214150f242SShaveta Leekha 	5250,
224150f242SShaveta Leekha 	5375,
234150f242SShaveta Leekha 	5500,
244150f242SShaveta Leekha 	5625,
254150f242SShaveta Leekha 	5750,
264150f242SShaveta Leekha 	5875,
274150f242SShaveta Leekha 	6000,
284150f242SShaveta Leekha 	6125,
294150f242SShaveta Leekha 	6250,
304150f242SShaveta Leekha 	6375,
314150f242SShaveta Leekha 	6500,
324150f242SShaveta Leekha 	6625,
334150f242SShaveta Leekha 	6750,
344150f242SShaveta Leekha 	6875,
354150f242SShaveta Leekha 	7000,
364150f242SShaveta Leekha 	7125,
374150f242SShaveta Leekha 	7250,
384150f242SShaveta Leekha 	7375,
394150f242SShaveta Leekha 	7500,
404150f242SShaveta Leekha 	7625,
414150f242SShaveta Leekha 	7750,
424150f242SShaveta Leekha 	7875,
434150f242SShaveta Leekha 	8000,
444150f242SShaveta Leekha 	8125,
454150f242SShaveta Leekha 	8250,
464150f242SShaveta Leekha 	8375,
474150f242SShaveta Leekha 	8500,
484150f242SShaveta Leekha 	8625,
494150f242SShaveta Leekha 	8750,
504150f242SShaveta Leekha 	8875,
514150f242SShaveta Leekha 	9000,
524150f242SShaveta Leekha 	9125,
534150f242SShaveta Leekha 	9250,
544150f242SShaveta Leekha 	9375,
554150f242SShaveta Leekha 	9500,  /* 0.95mV */
564150f242SShaveta Leekha 	9625,
574150f242SShaveta Leekha 	9750,
584150f242SShaveta Leekha 	9875,
594150f242SShaveta Leekha 	10000,  /* 1.0V */
604150f242SShaveta Leekha 	10125,
614150f242SShaveta Leekha 	10250,
624150f242SShaveta Leekha 	10375,
634150f242SShaveta Leekha 	10500,
644150f242SShaveta Leekha 	10625,
654150f242SShaveta Leekha 	10750,
664150f242SShaveta Leekha 	10875,
674150f242SShaveta Leekha 	11000,
684150f242SShaveta Leekha 	11125,
694150f242SShaveta Leekha 	11250,
704150f242SShaveta Leekha 	11375,
714150f242SShaveta Leekha 	11500,
724150f242SShaveta Leekha 	11625,
734150f242SShaveta Leekha 	11750,
744150f242SShaveta Leekha 	11875,
754150f242SShaveta Leekha 	12000,
764150f242SShaveta Leekha 	12125,
774150f242SShaveta Leekha 	12250,
784150f242SShaveta Leekha 	12375,
794150f242SShaveta Leekha 	0,	/* reserved */
804150f242SShaveta Leekha };
814150f242SShaveta Leekha 
824150f242SShaveta Leekha 
834150f242SShaveta Leekha /* Read Data d from Register r of POL p */
844150f242SShaveta Leekha u8 dpm_rrp(uchar r)
854150f242SShaveta Leekha {
864150f242SShaveta Leekha 	u8 ret[5];
874150f242SShaveta Leekha 
884150f242SShaveta Leekha 	ret[0] = RRP_OPCODE;
894150f242SShaveta Leekha 	/* POL is 0 */
904150f242SShaveta Leekha 	ret[1] = 0;
914150f242SShaveta Leekha 	ret[2] = r;
924150f242SShaveta Leekha 	i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2);
934150f242SShaveta Leekha 	if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */
944150f242SShaveta Leekha 		debug("RRP_OPCODE returned success data is %x\n", ret[0]);
954150f242SShaveta Leekha 		return ret[0];
964150f242SShaveta Leekha 	} else {
974150f242SShaveta Leekha 		return -1;
984150f242SShaveta Leekha 	}
994150f242SShaveta Leekha }
1004150f242SShaveta Leekha 
1014150f242SShaveta Leekha /* Write Data d into DPM register r (RAM) */
1024150f242SShaveta Leekha int dpm_wrm(u8 r, u8 d)
1034150f242SShaveta Leekha {
1044150f242SShaveta Leekha 	u8 ret[5];
1054150f242SShaveta Leekha 
1064150f242SShaveta Leekha 	ret[0] = WRM_OPCODE;
1074150f242SShaveta Leekha 	ret[1] = r;
1084150f242SShaveta Leekha 	ret[2] = d;
1094150f242SShaveta Leekha 	i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1);
1104150f242SShaveta Leekha 	if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */
1114150f242SShaveta Leekha 		debug("WRM_OPCODE returned success data is %x\n", ret[0]);
1124150f242SShaveta Leekha 		return ret[0];
1134150f242SShaveta Leekha 	} else {
1144150f242SShaveta Leekha 		return -1;
1154150f242SShaveta Leekha 	}
1164150f242SShaveta Leekha }
1174150f242SShaveta Leekha 
1184150f242SShaveta Leekha /* Write Data d into Register r of POL(s) a */
1194150f242SShaveta Leekha int dpm_wrp(u8 r, u8 d)
1204150f242SShaveta Leekha {
1214150f242SShaveta Leekha 	u8 ret[7];
1224150f242SShaveta Leekha 
1234150f242SShaveta Leekha 	ret[0] = WRP_OPCODE;
1244150f242SShaveta Leekha 	/* only POL0 is present */
1254150f242SShaveta Leekha 	ret[1] = 0x01;
1264150f242SShaveta Leekha 	ret[2] = 0x00;
1274150f242SShaveta Leekha 	ret[3] = 0x00;
1284150f242SShaveta Leekha 	ret[4] = 0x00;
1294150f242SShaveta Leekha 	ret[5] = r;
1304150f242SShaveta Leekha 	ret[6] = d;
1314150f242SShaveta Leekha 	i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1);
1324150f242SShaveta Leekha 	if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */
1334150f242SShaveta Leekha 		debug("WRP_OPCODE returned success data is %x\n", ret[0]);
1344150f242SShaveta Leekha 		return 0;
1354150f242SShaveta Leekha 	} else {
1364150f242SShaveta Leekha 		return -1;
1374150f242SShaveta Leekha 	}
1384150f242SShaveta Leekha }
1394150f242SShaveta Leekha 
1404150f242SShaveta Leekha /* Uses the DPM command RRP */
1414150f242SShaveta Leekha u8 zm_read(uchar reg)
1424150f242SShaveta Leekha {
143*63a7578eSMasahiro Yamada 	return dpm_rrp(reg);
1444150f242SShaveta Leekha }
1454150f242SShaveta Leekha 
1464150f242SShaveta Leekha /* ZM_write --
1474150f242SShaveta Leekha 	Steps:
1484150f242SShaveta Leekha 	a. Write data to the register
1494150f242SShaveta Leekha 	b. Read data from register and compare to written value
1504150f242SShaveta Leekha 	c. Return return_code & voltage_read
1514150f242SShaveta Leekha */
1524150f242SShaveta Leekha u8 zm_write(u8 reg, u8 data)
1534150f242SShaveta Leekha {
1544150f242SShaveta Leekha 	u8 d;
1554150f242SShaveta Leekha 
1564150f242SShaveta Leekha 	/* write data to register */
1574150f242SShaveta Leekha 	dpm_wrp(reg, data);
1584150f242SShaveta Leekha 
1594150f242SShaveta Leekha 	/* read register and compare to written value */
1604150f242SShaveta Leekha 	d = dpm_rrp(reg);
1614150f242SShaveta Leekha 	if (d != data) {
1624150f242SShaveta Leekha 		printf("zm_write : Comparison register data failed\n");
1634150f242SShaveta Leekha 		return -1;
1644150f242SShaveta Leekha 	}
1654150f242SShaveta Leekha 
1664150f242SShaveta Leekha 	return d;
1674150f242SShaveta Leekha }
1684150f242SShaveta Leekha 
1694150f242SShaveta Leekha /* zm_write_out_voltage
1704150f242SShaveta Leekha  * voltage in 1/10 mV
1714150f242SShaveta Leekha  */
1724150f242SShaveta Leekha int zm_write_voltage(int voltage)
1734150f242SShaveta Leekha {
1744150f242SShaveta Leekha 	u8 reg = 0x7, vid;
1754150f242SShaveta Leekha 	uint16_t voltage_read;
1764150f242SShaveta Leekha 	u8 ret;
1774150f242SShaveta Leekha 
1784150f242SShaveta Leekha 	vid =  (voltage - 5000) / ZM_STEP;
1794150f242SShaveta Leekha 
1804150f242SShaveta Leekha 	ret = zm_write(reg, vid);
1814150f242SShaveta Leekha 	if (ret != -1) {
1824150f242SShaveta Leekha 		voltage_read = hex_to_1_10mv[ret];
1834150f242SShaveta Leekha 		debug("voltage set to %dmV\n", voltage_read/10);
1844150f242SShaveta Leekha 		return voltage_read;
1854150f242SShaveta Leekha 	}
1864150f242SShaveta Leekha 	return -1;
1874150f242SShaveta Leekha }
1884150f242SShaveta Leekha 
1894150f242SShaveta Leekha /* zm_read_out_voltage
1904150f242SShaveta Leekha  * voltage in 1/10 mV
1914150f242SShaveta Leekha  */
1924150f242SShaveta Leekha int zm_read_voltage(void)
1934150f242SShaveta Leekha {
1944150f242SShaveta Leekha 	u8 reg = 0x7;
1954150f242SShaveta Leekha 	u8 ret;
1964150f242SShaveta Leekha 	int voltage;
1974150f242SShaveta Leekha 
1984150f242SShaveta Leekha 	ret = zm_read(reg);
1994150f242SShaveta Leekha 	if (ret != -1) {
2004150f242SShaveta Leekha 		voltage =  hex_to_1_10mv[ret];
2014150f242SShaveta Leekha 		debug("Voltage read is %dmV\n", voltage/10);
2024150f242SShaveta Leekha 		return voltage;
2034150f242SShaveta Leekha 	} else {
2044150f242SShaveta Leekha 		return -1;
2054150f242SShaveta Leekha 	}
2064150f242SShaveta Leekha }
2074150f242SShaveta Leekha 
2084150f242SShaveta Leekha int zm_disable_wp()
2094150f242SShaveta Leekha {
2104150f242SShaveta Leekha 	u8 new_wp_value;
2114150f242SShaveta Leekha 
2124150f242SShaveta Leekha 	/* Disable using Write-Protect register 0x96 */
2134150f242SShaveta Leekha 	new_wp_value = 0x8;
2144150f242SShaveta Leekha 	if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) {
2154150f242SShaveta Leekha 		printf("Disable Write-Protect register failed\n");
2164150f242SShaveta Leekha 		return -1;
2174150f242SShaveta Leekha 	}
2184150f242SShaveta Leekha 	return 0;
2194150f242SShaveta Leekha }
2204150f242SShaveta Leekha 
2214150f242SShaveta Leekha int zm_enable_wp()
2224150f242SShaveta Leekha {
2234150f242SShaveta Leekha 	u8 orig_wp_value;
2244150f242SShaveta Leekha 	orig_wp_value = 0x0;
2254150f242SShaveta Leekha 
2264150f242SShaveta Leekha 	/* Enable using Write-Protect register 0x96 */
2274150f242SShaveta Leekha 	if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) {
2284150f242SShaveta Leekha 		printf("Enable Write-Protect register failed\n");
2294150f242SShaveta Leekha 		return -1;
2304150f242SShaveta Leekha 	}
2314150f242SShaveta Leekha 	return 0;
2324150f242SShaveta Leekha }
2334150f242SShaveta Leekha 
234