mvsas: add SGPIO support to Marvell 94xx
PATCH 1/1 mvsas: add SGPIO support to Marvell 94xx
add SGPIO support to Marvell 94xx
---
drivers/scsi/mvsas/mv_94xx.c | 134 +++++++++++++++++++++++++++++++++ drivers/scsi/mvsas/mv_94xx.h | 71 +++++++++++++++++ drivers/scsi/mvsas/mv_init.c | 2 drivers/scsi/mvsas/mv_sas.c | 13 +++ drivers/scsi/mvsas/mv_sas.h | 5 + 5 files changed, 225 insertions(+)
drivers/scsi/mvsas/mv_94xx.c +134 -0
@@ -330,6 +330,51 @@ static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)mvs_write_port_vsr_data (mvi, phy_id, tmp &0xfd7fffff ); } +static void mvs_94xx_sgpio_init (struct mvs_info *mvi) +{ +void __iomem *regs = mvi->regs_ex -0x10200 ; +u32 tmp; + + tmp =mr32 (MVS_HST_CHIP_CONFIG ); + tmp |=0x100 ; +mw32 (MVS_HST_CHIP_CONFIG , tmp); + +mw32 (MVS_SGPIO_CTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +MVS_SGPIO_CTRL_SDOUT_AUTO <<MVS_SGPIO_CTRL_SDOUT_SHIFT ); + +mw32 (MVS_SGPIO_CFG1 +MVS_SGPIO_HOST_OFFSET * mvi->id, +8 <<MVS_SGPIO_CFG1_LOWA_SHIFT | +8 <<MVS_SGPIO_CFG1_HIA_SHIFT | +4 <<MVS_SGPIO_CFG1_LOWB_SHIFT | +4 <<MVS_SGPIO_CFG1_HIB_SHIFT | +2 <<MVS_SGPIO_CFG1_MAXACTON_SHIFT | +1 <<MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT + ); + +mw32 (MVS_SGPIO_CFG2 +MVS_SGPIO_HOST_OFFSET * mvi->id, + (300000 /100 ) <<MVS_SGPIO_CFG2_CLK_SHIFT |/* 100kHz clock */ +66 <<MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/ + ); + +mw32 (MVS_SGPIO_CFG0 +MVS_SGPIO_HOST_OFFSET * mvi->id, +MVS_SGPIO_CFG0_ENABLE | +MVS_SGPIO_CFG0_BLINKA | +MVS_SGPIO_CFG0_BLINKB | +/* 3*4 data bits / PDU */ + (12 -1 ) <<MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT + ); + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +DEFAULT_SGPIO_BITS ); + +mw32 (MVS_SGPIO_DSRC +MVS_SGPIO_HOST_OFFSET * mvi->id, + ((mvi->id *4 ) +3 ) << (8 *3 ) | + ((mvi->id *4 ) +2 ) << (8 *2 ) | + ((mvi->id *4 ) +1 ) << (8 *1 ) | + ((mvi->id *4 ) +0 ) << (8 *0 )); + +} +static int mvs_94xx_init (struct mvs_info *mvi) {void __iomem *regs = mvi->regs;
@@ -533,6 +578,8 @@ static int mvs_94xx_init(struct mvs_info *mvi)/* Enable SRS interrupt */ mw32 (MVS_INT_MASK_SRS_0 ,0xFFFF ); +mvs_94xx_sgpio_init (mvi); +return 0 ; }
@@ -1005,6 +1052,92 @@ static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) } +static int mvs_94xx_gpio_write (struct mvs_prv_info *mvs_prv, +u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data) +{ +int i; + +switch (reg_type) { + +case SAS_GPIO_REG_TX_GP : +if (reg_index ==0 ) +return -EINVAL ; + +if (reg_count >1 ) +return -EINVAL ; + +if (reg_count ==0 ) +return 0 ; + +/* maximum supported bits = hosts * 4 drives * 3 bits */ +for (i =0 ; i < mvs_prv->n_host *4 *3 ; i++) { + +/* select host */ +struct mvs_info *mvi = mvs_prv->mvi[i/(4 *3 )]; + +void __iomem *regs = mvi->regs_ex -0x10200 ; + +int drive = (i/3 ) & (4 -1 );/* drive number on host */ +u32 block =mr32 (MVS_SGPIO_DCTRL + +MVS_SGPIO_HOST_OFFSET * mvi->id); + + +/* +* if bit is set then create a mask with the first +* bit of the drive set in the mask ... +*/ +u32 bit = (write_data[i/8 ] & (1 << (i&(8 -1 )))) ? +1 <<(24 -drive*8 ) :0 ; + +/* +* ... and then shift it to the right position based +* on the led type (activity/id/fail) +*/ +switch (i%3 ) { +case 0 :/* activity */ + block &= ~((0x7 <<MVS_SGPIO_DCTRL_ACT_SHIFT ) + << (24 -drive*8 )); +/* hardwire activity bit to SOF */ + block |= led_blinka_sof << ( +MVS_SGPIO_DCTRL_ACT_SHIFT + + (24 -drive*8 )); +break ; +case 1 :/* id */ + block &= ~((0x3 <<MVS_SGPIO_DCTRL_LOC_SHIFT ) + << (24 -drive*8 )); + block |= bit <<MVS_SGPIO_DCTRL_LOC_SHIFT ; +break ; +case 2 :/* fail */ + block &= ~((0x7 <<MVS_SGPIO_DCTRL_ERR_SHIFT ) + << (24 -drive*8 )); + block |= bit <<MVS_SGPIO_DCTRL_ERR_SHIFT ; +break ; + } + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, + block); + + } + +return reg_count; + +case SAS_GPIO_REG_TX : +if (reg_index + reg_count > mvs_prv->n_host) +return -EINVAL ; + +for (i =0 ; i < reg_count; i++) { +struct mvs_info *mvi = mvs_prv->mvi[i+reg_index]; +void __iomem *regs = mvi->regs_ex -0x10200 ; + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +be32_to_cpu (((u32 *) write_data)[i])); + } +return reg_count; + } +return -ENOSYS ; +} +const struct mvs_dispatch mvs_94xx_dispatch = {"mv94xx" , mvs_94xx_init,
@@ -1057,5 +1190,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = { mvs_94xx_fix_dma, mvs_94xx_tune_interrupt, mvs_94xx_non_spec_ncq_error, + mvs_94xx_gpio_write, };
drivers/scsi/mvsas/mv_94xx.h +71 -0
83 lines not on this page · raw message
drivers/scsi/mvsas/mv_init.c +2 -0
@@ -85,6 +85,8 @@ static struct sas_domain_function_template mvs_transport_ops = { .lldd_port_formed = mvs_port_formed, .lldd_port_deformed = mvs_port_deformed, + .lldd_write_gpio = mvs_gpio_write, + };static void mvs_phy_init (struct mvs_info *mvi,int phy_id)
drivers/scsi/mvsas/mv_sas.c +13 -0
@@ -2103,3 +2103,16 @@ int mvs_int_rx(struct mvs_info *mvi, bool self_clear)return 0 ; } +int mvs_gpio_write (struct sas_ha_struct *sha,u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data) +{ +struct mvs_prv_info *mvs_prv = sha->lldd_ha; +struct mvs_info *mvi = mvs_prv->mvi[0 ]; + +if (MVS_CHIP_DISP ->gpio_write) { +return MVS_CHIP_DISP ->gpio_write (mvs_prv, reg_type, + reg_index, reg_count, write_data); + } + +return -ENOSYS ; +}
drivers/scsi/mvsas/mv_sas.h +5 -0
@@ -103,6 +103,7 @@ enum dev_reset { };struct mvs_info ; +struct mvs_prv_info ;struct mvs_dispatch {char *name;
@@ -172,6 +173,8 @@ struct mvs_dispatch { int buf_len, int from, void *prd);void (*tune_interrupt)(struct mvs_info *mvi,u32 time);void (*non_spec_ncq_error)(struct mvs_info *mvi); +int (*gpio_write)(struct mvs_prv_info *mvs_prv,u8 reg_type, +u8 reg_index,u8 reg_count,u8 *write_data); };
@@ -476,5 +479,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events);void mvs_update_phyinfo (struct mvs_info *mvi,int i,int get_st);int mvs_int_rx (struct mvs_info *mvi,bool self_clear);struct mvs_device *mvs_find_dev_by_reg_set (struct mvs_info *mvi,u8 reg_set); +int mvs_gpio_write (struct sas_ha_struct *,u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data);#endif
Quoted 12 lines · Wilfried Weissmann
add SGPIO support to Marvell 94xx
Signed-off-by Wilfried Weissmann <[email protected]>---
drivers/scsi/mvsas/mv_94xx.c | 134 +++++++++++++++++++++++++++++++++ drivers/scsi/mvsas/mv_94xx.h | 71 +++++++++++++++++ drivers/scsi/mvsas/mv_init.c | 2 drivers/scsi/mvsas/mv_sas.c | 13 +++ drivers/scsi/mvsas/mv_sas.h | 5 + 5 files changed, 225 insertions(+)
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Wilfried" == Wilfried Weissmann <[email protected]> writes:
Wilfried,
Wilfried> add SGPIO support to Marvell 94xx
Does not apply to current tree. Please rebase on top of:
http://git.kernel.org/cgit/linux/kernel/git/mkp/scsi.git/log/?h=4.5/scsi-queue
Thank you!
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
add SGPIO support to Marvell 94xx
---
rebased to http://git.kernel.org/cgit/linux/kernel/git/mkp/scsi.git/log/?h=4.5/scsi-queue
changed enum sgpio_led_status members to uppercase
drivers/scsi/mvsas/mv_94xx.c | 134 +++++++++++++++++++++++++++++++++ drivers/scsi/mvsas/mv_94xx.h | 71 +++++++++++++++++ drivers/scsi/mvsas/mv_init.c | 2 drivers/scsi/mvsas/mv_sas.c | 13 +++ drivers/scsi/mvsas/mv_sas.h | 5 + 5 files changed, 225 insertions(+)
drivers/scsi/mvsas/mv_94xx.c +134 -0
@@ -330,6 +330,51 @@ static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)mvs_write_port_vsr_data (mvi, phy_id, tmp &0xfd7fffff ); } +static void mvs_94xx_sgpio_init (struct mvs_info *mvi) +{ +void __iomem *regs = mvi->regs_ex -0x10200 ; +u32 tmp; + + tmp =mr32 (MVS_HST_CHIP_CONFIG ); + tmp |=0x100 ; +mw32 (MVS_HST_CHIP_CONFIG , tmp); + +mw32 (MVS_SGPIO_CTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +MVS_SGPIO_CTRL_SDOUT_AUTO <<MVS_SGPIO_CTRL_SDOUT_SHIFT ); + +mw32 (MVS_SGPIO_CFG1 +MVS_SGPIO_HOST_OFFSET * mvi->id, +8 <<MVS_SGPIO_CFG1_LOWA_SHIFT | +8 <<MVS_SGPIO_CFG1_HIA_SHIFT | +4 <<MVS_SGPIO_CFG1_LOWB_SHIFT | +4 <<MVS_SGPIO_CFG1_HIB_SHIFT | +2 <<MVS_SGPIO_CFG1_MAXACTON_SHIFT | +1 <<MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT + ); + +mw32 (MVS_SGPIO_CFG2 +MVS_SGPIO_HOST_OFFSET * mvi->id, + (300000 /100 ) <<MVS_SGPIO_CFG2_CLK_SHIFT |/* 100kHz clock */ +66 <<MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/ + ); + +mw32 (MVS_SGPIO_CFG0 +MVS_SGPIO_HOST_OFFSET * mvi->id, +MVS_SGPIO_CFG0_ENABLE | +MVS_SGPIO_CFG0_BLINKA | +MVS_SGPIO_CFG0_BLINKB | +/* 3*4 data bits / PDU */ + (12 -1 ) <<MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT + ); + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +DEFAULT_SGPIO_BITS ); + +mw32 (MVS_SGPIO_DSRC +MVS_SGPIO_HOST_OFFSET * mvi->id, + ((mvi->id *4 ) +3 ) << (8 *3 ) | + ((mvi->id *4 ) +2 ) << (8 *2 ) | + ((mvi->id *4 ) +1 ) << (8 *1 ) | + ((mvi->id *4 ) +0 ) << (8 *0 )); + +} +static int mvs_94xx_init (struct mvs_info *mvi) {void __iomem *regs = mvi->regs;
@@ -533,6 +578,8 @@ static int mvs_94xx_init(struct mvs_info *mvi)/* Enable SRS interrupt */ mw32 (MVS_INT_MASK_SRS_0 ,0xFFFF ); +mvs_94xx_sgpio_init (mvi); +return 0 ; }
@@ -1005,6 +1052,92 @@ static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time) } +static int mvs_94xx_gpio_write (struct mvs_prv_info *mvs_prv, +u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data) +{ +int i; + +switch (reg_type) { + +case SAS_GPIO_REG_TX_GP : +if (reg_index ==0 ) +return -EINVAL ; + +if (reg_count >1 ) +return -EINVAL ; + +if (reg_count ==0 ) +return 0 ; + +/* maximum supported bits = hosts * 4 drives * 3 bits */ +for (i =0 ; i < mvs_prv->n_host *4 *3 ; i++) { + +/* select host */ +struct mvs_info *mvi = mvs_prv->mvi[i/(4 *3 )]; + +void __iomem *regs = mvi->regs_ex -0x10200 ; + +int drive = (i/3 ) & (4 -1 );/* drive number on host */ +u32 block =mr32 (MVS_SGPIO_DCTRL + +MVS_SGPIO_HOST_OFFSET * mvi->id); + + +/* +* if bit is set then create a mask with the first +* bit of the drive set in the mask ... +*/ +u32 bit = (write_data[i/8 ] & (1 << (i&(8 -1 )))) ? +1 <<(24 -drive*8 ) :0 ; + +/* +* ... and then shift it to the right position based +* on the led type (activity/id/fail) +*/ +switch (i%3 ) { +case 0 :/* activity */ + block &= ~((0x7 <<MVS_SGPIO_DCTRL_ACT_SHIFT ) + << (24 -drive*8 )); +/* hardwire activity bit to SOF */ + block |=LED_BLINKA_SOF << ( +MVS_SGPIO_DCTRL_ACT_SHIFT + + (24 -drive*8 )); +break ; +case 1 :/* id */ + block &= ~((0x3 <<MVS_SGPIO_DCTRL_LOC_SHIFT ) + << (24 -drive*8 )); + block |= bit <<MVS_SGPIO_DCTRL_LOC_SHIFT ; +break ; +case 2 :/* fail */ + block &= ~((0x7 <<MVS_SGPIO_DCTRL_ERR_SHIFT ) + << (24 -drive*8 )); + block |= bit <<MVS_SGPIO_DCTRL_ERR_SHIFT ; +break ; + } + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, + block); + + } + +return reg_count; + +case SAS_GPIO_REG_TX : +if (reg_index + reg_count > mvs_prv->n_host) +return -EINVAL ; + +for (i =0 ; i < reg_count; i++) { +struct mvs_info *mvi = mvs_prv->mvi[i+reg_index]; +void __iomem *regs = mvi->regs_ex -0x10200 ; + +mw32 (MVS_SGPIO_DCTRL +MVS_SGPIO_HOST_OFFSET * mvi->id, +be32_to_cpu (((u32 *) write_data)[i])); + } +return reg_count; + } +return -ENOSYS ; +} +const struct mvs_dispatch mvs_94xx_dispatch = {"mv94xx" , mvs_94xx_init,
@@ -1057,5 +1190,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = { mvs_94xx_fix_dma, mvs_94xx_tune_interrupt, mvs_94xx_non_spec_ncq_error, + mvs_94xx_gpio_write, };
drivers/scsi/mvsas/mv_94xx.h +71 -0
83 lines not on this page · raw message
drivers/scsi/mvsas/mv_init.c +2 -0
@@ -84,6 +84,8 @@ static struct sas_domain_function_template mvs_transport_ops = { .lldd_port_formed = mvs_port_formed, .lldd_port_deformed = mvs_port_deformed, + .lldd_write_gpio = mvs_gpio_write, + };static void mvs_phy_init (struct mvs_info *mvi,int phy_id)
drivers/scsi/mvsas/mv_sas.c +13 -0
@@ -2105,3 +2105,16 @@ int mvs_int_rx(struct mvs_info *mvi, bool self_clear)return 0 ; } +int mvs_gpio_write (struct sas_ha_struct *sha,u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data) +{ +struct mvs_prv_info *mvs_prv = sha->lldd_ha; +struct mvs_info *mvi = mvs_prv->mvi[0 ]; + +if (MVS_CHIP_DISP ->gpio_write) { +return MVS_CHIP_DISP ->gpio_write (mvs_prv, reg_type, + reg_index, reg_count, write_data); + } + +return -ENOSYS ; +}
drivers/scsi/mvsas/mv_sas.h +5 -0
@@ -103,6 +103,7 @@ enum dev_reset { };struct mvs_info ; +struct mvs_prv_info ;struct mvs_dispatch {char *name;
@@ -172,6 +173,8 @@ struct mvs_dispatch { int buf_len, int from, void *prd);void (*tune_interrupt)(struct mvs_info *mvi,u32 time);void (*non_spec_ncq_error)(struct mvs_info *mvi); +int (*gpio_write)(struct mvs_prv_info *mvs_prv,u8 reg_type, +u8 reg_index,u8 reg_count,u8 *write_data); };
@@ -476,5 +479,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events);void mvs_update_phyinfo (struct mvs_info *mvi,int i,int get_st);int mvs_int_rx (struct mvs_info *mvi,bool self_clear);struct mvs_device *mvs_find_dev_by_reg_set (struct mvs_info *mvi,u8 reg_set); +int mvs_gpio_write (struct sas_ha_struct *,u8 reg_type,u8 reg_index, +u8 reg_count,u8 *write_data);#endif
James Bottomley
maintainerQuoted 1 line · Wilfried Weissmann
add SGPIO support to Marvell 94xx
How do you actually use this? It doesn't seem to be plumbed into the standard GPIO subsystem and there appears to be no user accessible interface for it either (nor is it used internally).
There doesn't appear to be much point adding an unusable feature.
James
Am 27.12.15 um 20:42 schrieb James Bottomley:
Quoted 8 lines · Wilfried Weissmann
Quoted 1 line
add SGPIO support to Marvell 94xx
How do you actually use this? It doesn't seem to be plumbed into the standard GPIO subsystem and there appears to be no user accessible interface for it either (nor is it used internally).
There doesn't appear to be much point adding an unusable feature.
sas_domain_function_template.lldd_write_gpio exposes the interface to libsas. Userspace access is then done via ioctl(SG_IO,...). Existing user space tools such as ledmon use this method, also smp_utils in case you want to have more direct control.
Greetings,
Wilfried
Quoted 9 lines · Wilfried Weissmann
Am 27.12.15 um 20:42 schrieb James Bottomley:
Quoted 8 lines · Wilfried Weissmann
Quoted 1 line
add SGPIO support to Marvell 94xx
How do you actually use this? It doesn't seem to be plumbed into the
standard GPIO subsystem and there appears to be no user accessible interface for it either (nor is it used internally).
Quoted 6 lines
Quoted 1 line
There doesn't appear to be much point adding an unusable feature.
sas_domain_function_template.lldd_write_gpio exposes the interface to libsas. Userspace access is then done via
ioctl(SG_IO,...). Existing user space tools such as ledmon use this method, alsosmp_utilsin case you want to have more direct control.
Ah, right, I'd forgotten that got added.
Thanks,
James
Martin K. Petersen
AppliedQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Wilfried" == Wilfried Weissmann <[email protected]> writes:
Wilfried> add SGPIO support to Marvell 94xx
Applied to 4.5/scsi-queue.
Thanks!
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering