Jz47xx.c

From Qi-Hardware
Jump to: navigation, search
  1. /*
  2.  * $Id: jz47xx.c $
  3.  * emQbit LTDA.
  4.  * Carlos Iván Camargo Bareño
  5.  * Based on Vision EP9307 SoM GPIO JTAG Cable Driver
  6.  * Copyright (C) 2007, 2008 H Hartley Sweeten
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  21.  * 02111-1307, USA.
  22.  *
  23.  * Written by Carlos Camargo Bareño <carlos@emqbit.com>, 2010
  24.  *
  25.  */
  26.  
  27. #include "sysdep.h"
  28.  
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <sys/mman.h>
  35. #include <fcntl.h>
  36. #include <unistd.h>
  37.  
  38. #include <urjtag/cable.h>
  39. #include <urjtag/chain.h>
  40.  
  41. #include "generic.h"
  42. #include "jz47xx_gpio.h"
  43.  
  44. #include <cmd.h>
  45.  
  46.  
  47. #define JZ_GPIO_BASE		0x10010000
  48.  
  49. typedef struct {
  50. 	int		fd_dev_mem;
  51. 	size_t		map_size;
  52. 	JZ_PIO		*pio_base;
  53. 	int		signals;
  54. 	uint32_t	lastout;
  55. } jz47xx_params_t;
  56.  
  57.  
  58. PJZ_PIO* pio;
  59.  
  60. static void 
  61. jz_gpio_as_output (int port, unsigned int o)
  62. {
  63.   pio[port]->PXFUNC = (1 << (o));
  64.   pio[port]->PXSELC = (1 << (o));
  65.   pio[port]->PXDIRS = (1 << (o));
  66. }
  67.  
  68. static void 
  69. jz_gpio_as_input (int port, unsigned int o)
  70. {
  71.   pio[port]->PXFUNC = (1 << (o));
  72.   pio[port]->PXSELC = (1 << (o));
  73.   pio[port]->PXDIRC = (1 << (o));
  74. }
  75.  
  76. static void 
  77. jz_gpio_set_pin (int port, unsigned int o)
  78. {
  79.   pio[port]->PXDATS = (1 << (o));
  80. }
  81.  
  82. static void 
  83. jz_gpio_clear_pin (int port, unsigned int o)
  84. {
  85.   pio[port]->PXDATC = (1 << (o));
  86. }
  87.  
  88. static void 
  89. jz_gpio_out (int port, unsigned int o, unsigned int val)
  90. {
  91.   if (val == 0)
  92.     pio[port]->PXDATC = (1 << (o));
  93.   else
  94.     pio[port]->PXDATS = (1 << (o));
  95. }
  96.  
  97. static unsigned int 
  98. jz_gpio_get_pin (int port, unsigned int o)
  99. {
  100.   return (pio[port]->PXPIN & (1 << o)) ? 1 : 0;
  101. }
  102.  
  103.  
  104. static int 
  105. jz47xx_gpio_open( urj_cable_t *cable )
  106. {
  107.   unsigned char port;
  108.  
  109.   pio = (PJZ_PIO*)malloc(sizeof(PJZ_PIO)*4);
  110.   jz47xx_params_t *p = cable->params;
  111.  
  112.   /* Open the memory device so we can access the hardware registers */
  113.   p->map_size = sizeof(PJZ_PIO)*4;
  114.   if ((p->fd_dev_mem = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
  115.     {cable_t
  116.       fprintf (stderr, "Cannot open /dev/mem.\n");
  117.       return 0;
  118.     }
  119.  
  120.   /* Map the System Controller registers */
  121.   p->pio_base = (JZ_PIO *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, p->fd_dev_mem, JZ_GPIO_BASE);
  122.   if (p-> pio_base == (JZ_PIO *) - 1)
  123.     {
  124.       fprintf (stderr, "Cannot mmap.\n");
  125.       return 0;
  126.     }
  127.  
  128.   for(port=0; port<4; port++)
  129.     pio[port] = (JZ_PIO *) ((unsigned int) p->pio_base + port * 0x100);
  130.  
  131.   /* Set the GPIO pins as inputs/outputs as needed for the JTAG interface */
  132.   jz_gpio_as_input  (JZ_GPIO_PORT_D, TDO);
  133.   jz_gpio_as_output (JZ_GPIO_PORT_D, TCK);
  134.   jz_gpio_as_output (JZ_GPIO_PORT_C, TDI);
  135.   jz_gpio_as_output (JZ_GPIO_PORT_D, TMS);
  136.  
  137.   jz_gpio_as_output (JZ_GPIO_PORT_C, 17);
  138.   jz_gpio_set_pin (JZ_GPIO_PORT_C, 17);
  139.  
  140.   return 0;
  141. }
  142.  
  143. static int
  144. jz47xx_gpio_close( urj_cable_t *cable )
  145. {
  146.  
  147. 	jz47xx_params_t *p = cable->params;
  148.  
  149.  
  150. 	if (munmap(p->pio_base, p->map_size) == -1) {
  151. 		printf( _("Error: unable to munmap the GPIO registers\n"));
  152. 	}
  153. 	close(p->fd_dev_mem);
  154. 	return 0;
  155. }
  156.  
  157.  
  158. static int
  159. jz47xx_connect( urj_cable_t *cable, const urj_param_t *params[] )
  160. {
  161. 	jz47xx_params_t *cable_params;
  162.  
  163. 	if ( urj_param_num (params) > 0) {
  164. 	  printf( _("Error: This cable type does not acable_tccept parameters!\n") );
  165. 	  return 1;
  166. 	}
  167.  
  168. 	printf( _("Initializing SIE Built-in JTAG Chain\n") );
  169.  
  170. 	cable_params = malloc( sizeof *cable_params );
  171. 	if (!cable_params) {
  172. 		printf( _("%s(%d) Out of memory\n"), __FILE__, __LINE__ );
  173. 		free( cable );
  174. 		return 4;
  175. 	}
  176.  
  177. 	cable->params = cable_params;
  178. 	cable->chain = NULL;
  179. 	cable->delay = 1000;
  180. 	return 0;
  181. }
  182.  
  183. static void
  184. jz47xx_disconnect( urj_cable_t *cable )
  185. {
  186. 	jz47xx_gpio_close( cable );
  187. 	urj_tap_chain_disconnect( cable->chain );
  188. }
  189.  
  190. static void
  191. jz47xx_cable_free( urj_cable_t *cable )
  192. {
  193. 	free( cable->params );
  194. 	free( cable );
  195. }
  196.  
  197. static int
  198. jz47xx_init( urj_cable_t *cable )
  199. {
  200. 	if (jz47xx_gpio_open( cable ))
  201. 		return -1;
  202.  
  203. 	return 0;
  204. }
  205.  
  206. static void
  207. jz47xx_done( urj_cable_t *cable )
  208. {
  209. 	jz47xx_gpio_close( cable );
  210. }
  211.  
  212. static void
  213. jz47xx_clock( urj_cable_t *cable, int tms, int tdi, int n )
  214. {
  215. 	int i;
  216.  
  217. 	tms = tms ? 1 : 0;
  218. 	tdi = tdi ? 1 : 0;
  219.  
  220. 	jz_gpio_out (JZ_GPIO_PORT_C, TDI, tdi);
  221. 	jz_gpio_out (JZ_GPIO_PORT_D, TMS, tms);
  222.  
  223. 	for (i = 0; i < n; i++) {
  224.  
  225. 		jz_gpio_out (JZ_GPIO_PORT_D, TCK, 0);
  226. 		jz_gpio_out (JZ_GPIO_PORT_D, TCK, 1);
  227. 		jz_gpio_out (JZ_GPIO_PORT_D, TCK, 0);
  228. 	}
  229. }
  230.  
  231. /**
  232.  * NOTE: This also lowers the TDI and TMS lines; is this intended?
  233.  */
  234. static int
  235. jz47xx_get_tdo( urj_cable_t *cable )
  236. {
  237. 	jz_gpio_out (JZ_GPIO_PORT_D, TCK, 0);
  238. 	return jz_gpio_get_pin (JZ_GPIO_PORT_D, TDO);
  239. }
  240.  
  241. static int
  242. jz47xx_current_signals( urj_cable_t *cable )
  243. {
  244. 	jz47xx_params_t *p = cable->params;
  245.  
  246. 	int sigs = p->signals & ~(URJ_POD_CS_TMS | URJ_POD_CS_TDI | URJ_POD_CS_TCK);
  247. 	if (p->lastout & (1 << TCK)) sigs |= URJ_POD_CS_TCK;
  248. 	if (p->lastout & (1 << TDI)) sigs |= URJ_POD_CS_TDI;
  249. 	if (p->lastout & (1 << TMS)) sigs |= URJ_POD_CS_TMS;
  250.  
  251. 	return sigs;
  252. }
  253.  
  254. static int
  255. jz47xx_set_signal( urj_cable_t *cable, int mask, int val )
  256. {
  257.  
  258. 	int prev_sigs = jz47xx_current_signals( cable );
  259.  
  260. 	mask &= (URJ_POD_CS_TDI | URJ_POD_CS_TCK | URJ_POD_CS_TMS); // only these can be modified
  261. 	if (mask != 0)
  262. 	{
  263. 		int sigs = (prev_sigs & ~mask) | (val & mask);
  264. 		int tms = (sigs & URJ_POD_CS_TMS) ? (1 << TMS) : 0;
  265. 		int tdi = (sigs & URJ_POD_CS_TDI) ? (1 << TDI) : 0;
  266. 		int tck = (sigs & URJ_POD_CS_TCK) ? (1 << TCK) : 0;
  267. 		jz_gpio_out (JZ_GPIO_PORT_C, TDI, tdi);
  268. 		jz_gpio_out (JZ_GPIO_PORT_D, TMS, tms);
  269. 		jz_gpio_out (JZ_GPIO_PORT_D, TCK, tck);
  270. 	}
  271. 	return prev_sigs;
  272. }
  273.  
  274. static int
  275. jz47xx_get_signal( urj_cable_t *cable,urj_pod_sigsel_t sig )
  276. {
  277.  
  278. 	return (jz47xx_current_signals( cable ) & sig) ? 1 : 0;
  279. }
  280.  
  281. static void
  282. jz47xx_help( const char *cablename )
  283. {
  284. 	printf( _(
  285. 		"Usage: cable %s\n"
  286. 		"\n"
  287. 	), cablename );
  288. }
  289.  
  290. const urj_cable_driver_t urj_tap_cable_jz47xx_driver = {
  291. 	"jz47xx",
  292. 	N_("SIE board GPIO JTAG controller"),
  293.     	URJ_CABLE_DEVICE_OTHER,
  294.     	{ .other = jz47xx_connect, },
  295. 	jz47xx_disconnect,
  296. 	jz47xx_cable_free,
  297. 	jz47xx_init,
  298. 	jz47xx_done,
  299. 	urj_tap_cable_generic_set_frequency,
  300. 	jz47xx_clock,
  301. 	jz47xx_get_tdo,
  302. 	urj_tap_cable_generic_transfer,
  303. 	jz47xx_set_signal,
  304. 	jz47xx_get_signal,
  305. 	urj_tap_cable_generic_flush_one_by_one,
  306. 	jz47xx_help
  307. };
Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export