NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-i386/56051: finsio at isa* unusable



>Number:         56051
>Category:       port-i386
>Synopsis:       finsio at isa* unusable
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-i386-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 11 14:15:00 +0000 2021
>Originator:     Jean-Yves Moulin
>Release:        9.1
>Organization:
Baaz
>Environment:
NetBSD olifant.baaz.fr 9.1 NetBSD 9.1 (OLIFANT) #27: Thu Mar 11 10:05:11 CET 2021  jym%olifant.baaz.fr@localhost:/usr/obj/sys/arch/i386/compile/OLIFANT i386
>Description:
In the kernel, the finsio driver (Fintek Super I/O chip used for monitoring) is unusable on my computer (and certainly all others computer with this chip).

Some registers used in initialization function are not accessed correctly.

Adding it in the kernel configuration make the kernel unbootable.
>How-To-Repeat:
Add :

finsio0        at isa? port 0x4e

in the kernel configuration of a computer with Fintek chip. Build it, install it and reboot.
>Fix:
Below is the patch:

Beware: with this patch, a kernel with finsio boots fine and provides value to envsys. But some voltage readings are erroneous. We need to check resistor value.

*** finsio_isa.c.orig	2021-03-11 10:13:18.234482734 +0100
--- finsio_isa.c	2021-03-11 10:12:50.622545418 +0100
***************
*** 54,60 ****
  #define FINSIO_LOCK	0xaa	/* magic constant - write 1x to deselect reg */
  
  #define FINSIO_FUNC_SEL	0x07	/* select which subchip to access */
! #  define FINSIO_FUNC_HWMON 0x4
  
  /* ISA registers index to an internal register space on chip */
  #define FINSIO_DECODE_SIZE (8)
--- 54,60 ----
  #define FINSIO_LOCK	0xaa	/* magic constant - write 1x to deselect reg */
  
  #define FINSIO_FUNC_SEL	0x07	/* select which subchip to access */
! #  define FINSIO_FUNC_HWMON 0x4	/* Should be 0x02 for f71858fg */
  
  /* ISA registers index to an internal register space on chip */
  #define FINSIO_DECODE_SIZE (8)
***************
*** 63,68 ****
--- 63,69 ----
  #define FINSIO_DATA	6	/* and data registers */
  
  /* Global configuration registers */
+ #define FINSIO_REVISION 0x22    /* chip revision */
  #define FINSIO_MANUF	0x23	/* manufacturer ID */
  # define FINTEK_ID	0x1934
  #define FINSIO_CHIP	0x20	/* chip ID */
***************
*** 71,76 ****
--- 72,78 ----
  # define FINSIO_IDF71883	0x0541	/* F71882 and F1883 */
  # define FINSIO_IDF71862 	0x0601	/* F71862FG */
  # define FINSIO_IDF8000 	0x0581	/* F8000 */
+ #define FINSIO_ENABLED  0x30        /* device enable */
  
  /* in bank sensors of config space */
  #define FINSIO_SENSADDR	0x60	/* sensors assigned I/O address (2 bytes) */
***************
*** 124,129 ****
--- 126,133 ----
  
  static void	finsio_enter(bus_space_tag_t, bus_space_handle_t);
  static void 	finsio_exit(bus_space_tag_t, bus_space_handle_t);
+ static uint8_t 	finsio_readio(bus_space_tag_t, bus_space_handle_t, int);
+ static void 	finsio_selectio(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val);
  static uint8_t 	finsio_readreg(bus_space_tag_t, bus_space_handle_t, int);
  static void 	finsio_writereg(bus_space_tag_t, bus_space_handle_t, int, int);
  
***************
*** 437,446 ****
  	if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh))
  		return 0;
  
  	finsio_enter(ia->ia_iot, ioh);
  	/* Find out Manufacturer ID */
! 	val = finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF) << 8;
! 	val |= finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF + 1);
  	finsio_exit(ia->ia_iot, ioh);
  	bus_space_unmap(ia->ia_iot, ioh, 2);
  
--- 441,453 ----
  	if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh))
  		return 0;
  
+ 
  	finsio_enter(ia->ia_iot, ioh);
+ 
  	/* Find out Manufacturer ID */
! 	val = finsio_readio(ia->ia_iot, ioh, FINSIO_MANUF) << 8;
! 	val |= finsio_readio(ia->ia_iot, ioh, FINSIO_MANUF + 1);
! 
  	finsio_exit(ia->ia_iot, ioh);
  	bus_space_unmap(ia->ia_iot, ioh, 2);
  
***************
*** 453,458 ****
--- 460,466 ----
  	ia->ia_nirq = 0;
  	ia->ia_ndrq = 0;
  
+ 
  	return 1;
  }
  
***************
*** 469,474 ****
--- 477,483 ----
  
  	sc->sc_iot = ia->ia_iot;
  
+ 
  	/* Map Super I/O configuration space */
  	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) {
  		aprint_error(": can't map configuration I/O space\n");
***************
*** 477,491 ****
  
  	finsio_enter(sc->sc_iot, ioh);
  	/* Get the Chip ID */
! 	chipid = finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP) << 8;
! 	chipid |= finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP + 1);
  	/* 
  	 * Select the Hardware Monitor LDN to find out the I/O
  	 * address space.
  	 */
! 	finsio_writereg(sc->sc_iot, ioh, FINSIO_FUNC_SEL, FINSIO_FUNC_HWMON);
! 	hwmon_baddr = finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR) << 8;
! 	hwmon_baddr |= finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR + 1);
  	finsio_exit(sc->sc_iot, ioh);
  	bus_space_unmap(sc->sc_iot, ioh, 2);
  
--- 486,500 ----
  
  	finsio_enter(sc->sc_iot, ioh);
  	/* Get the Chip ID */
! 	chipid = finsio_readio(sc->sc_iot, ioh, FINSIO_CHIP) << 8;
! 	chipid |= finsio_readio(sc->sc_iot, ioh, FINSIO_CHIP + 1);
  	/* 
  	 * Select the Hardware Monitor LDN to find out the I/O
  	 * address space.
  	 */
! 	finsio_selectio(sc->sc_iot, ioh, FINSIO_FUNC_SEL, FINSIO_FUNC_HWMON);
! 	hwmon_baddr = finsio_readio(sc->sc_iot, ioh, FINSIO_SENSADDR) << 8;
! 	hwmon_baddr |= finsio_readio(sc->sc_iot, ioh, FINSIO_SENSADDR + 1);
  	finsio_exit(sc->sc_iot, ioh);
  	bus_space_unmap(sc->sc_iot, ioh, 2);
  
***************
*** 590,604 ****
  static void
  finsio_enter(bus_space_tag_t iot, bus_space_handle_t ioh)
  {
! 	bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK);
! 	bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK);
  }
  
  /* Exit Super I/O configuration mode */
  static void
  finsio_exit(bus_space_tag_t iot, bus_space_handle_t ioh)
  {
! 	bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_LOCK);
  }
  
  static uint8_t
--- 599,627 ----
  static void
  finsio_enter(bus_space_tag_t iot, bus_space_handle_t ioh)
  {
! 	bus_space_write_1(iot, ioh, 0, FINSIO_UNLOCK);
! 	bus_space_write_1(iot, ioh, 0, FINSIO_UNLOCK);
  }
  
  /* Exit Super I/O configuration mode */
  static void
  finsio_exit(bus_space_tag_t iot, bus_space_handle_t ioh)
  {
! 	bus_space_write_1(iot, ioh, 0, FINSIO_LOCK);
! }
! 
! static uint8_t
! finsio_readio(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
! {
! 	bus_space_write_1(iot, ioh, 0, reg);
! 	return bus_space_read_1(iot, ioh, 1);
! }
! 
! static void
! finsio_selectio(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val)
! {
! 	bus_space_write_1(iot, ioh, 0, reg);
! 	bus_space_write_1(iot, ioh, 1, val);
  }
  
  static uint8_t



Home | Main Index | Thread Index | Old Index