From: Enric Balletbo Serra <eballetbo@gmail.com> To: Dan Carpenter <dan.carpenter@oracle.com> Cc: "devicetree@vger.kernel.org" <devicetree@vger.kernel.org>, linux-kernel@vger.kernel.org, dri-devel <dri-devel@lists.freedesktop.org>, devel@driverdev.osuosl.org, Thierry Reding <treding@nvidia.com>, Mark Rutland <mark.rutland@arm.com>, drinkcat@chromium.org, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Pawel Moll <pawel.moll@arm.com>, Ian Campbell <ijc+devicetree@hellion.org.uk>, airlied@linux.ie, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Emil Velikov <emil.l.velikov@gmail.com>, cawa cheng <cawa.cheng@mediatek.com>, Daniel Kurtz <djkurtz@chromium.org>, jb.tsai@mediatek.com, Sjoerd Simons <sjoerd.simons@collabora.co.uk>, Rob Herring <robh+dt@kernel.org>, span@analogixsemi.com, Kumar Gala <galak@codeaurora.org>, Javier Martinez Canillas <javier@dowhile0.org>, eddie.huang@mediatek.com, cjiao@analogixsemi.com, Nathan Chung <nathan.chung@mediatek.com> Subject: Re: [PATCHv6 5/5] drm: bridge: anx78xx: Add anx78xx driver support by analogix. Date: Wed, 9 Dec 2015 12:55:12 +0100 [thread overview] Message-ID: <CAFqH_51xtqzLRw30p-UfMSRe1A1zshwu9Nhg-s8xiChNCOpWmg@mail.gmail.com> (raw) In-Reply-To: <20151207080956.GB18797@mwanda> Hi Dan, Many thanks for your comments. 2015-12-07 9:09 GMT+01:00 Dan Carpenter <dan.carpenter@oracle.com>: > On Fri, Dec 04, 2015 at 09:35:07AM +0100, Enric Balletbo i Serra wrote: >> +static int sp_wait_aux_op_finish(struct anx78xx *anx78xx) >> +{ >> + u8 errcnt; >> + u8 val; >> + struct device *dev = &anx78xx->client->dev; >> + >> + errcnt = 150; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(2000, 4000); >> + } >> + >> + if (!errcnt) { > > This is off by one. It should be: > > while (--errcnt) { > ... > } > if (errcnt == 0) > return -EWHATEVER; > > Or: > > while (errcnt--) { > ... > } > if (errcnt == -1) > return -EWHATEVER; > > Also "errcnt" is a bad name, it should be retry_cnt or something (or > maybe it actually is counting errors?). Also -1 is never a correct > error code, please change all the -1 returns to something better. > Ok, I renamed to retry_cnt and changed all the -1 values to something better. >> + /* Buffer size of AUX CH is 16 */ >> + if (count > 16) >> + return -1; > > Just make a define so that you don't need to add comments about why 16 > is correct. > > if (count > SIZE_AUX_CH) > return -EINVAL; > Added a define >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(1000, 2000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP AUX Channel Control Register 2\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > Off by one again. > Ack > >> + >> + sp_reg_write(anx78xx, TX_P0, SP_AUX_ADDR_7_0_REG, SP_I2C_EXTRA_ADDR); >> + sp_tx_aux_wr(anx78xx, offset); >> + /* read 16 bytes (MOT = 1) */ >> + sp_tx_aux_rd(anx78xx, 0xf0 | DP_AUX_I2C_MOT | DP_AUX_I2C_READ); >> + >> + for (i = 0; i < 16; i++) { >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_BUF_DATA_COUNT_REG, >> + &val); >> + if (val & SP_BUF_DATA_COUNT_MASK) >> + break; >> + usleep_range(2000, 4000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP Buffer Data Count Register\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > And here. > Ack >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(1000, 2000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP AUX Channel Control Register 2\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > Here. > Ack > >> + >> + return 0; >> +} >> + >> +static int sp_edid_block_checksum(const u8 *raw_edid) >> +{ >> + int i; >> + u8 csum = 0; >> + >> + for (i = 0; i < EDID_LENGTH; i++) >> + csum += raw_edid[i]; >> + >> + return csum; >> +} >> + >> +static int sp_tx_edid_read(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 val, last_block, offset = 0; >> + u8 buf[16]; >> + int i, j, count; >> + >> + sp_tx_edid_read_initial(anx78xx); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL1_REG, 0x04); >> + sp_reg_set_bits(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, >> + SP_AUX_EN | SP_ADDR_ONLY); >> + >> + if (sp_wait_aux_op_finish(anx78xx)) >> + return -1; >> + >> + sp_addronly_set(anx78xx, false); >> + >> + /* Read the number of blocks */ >> + sp_tx_aux_wr(anx78xx, 0x7e); >> + sp_tx_aux_rd(anx78xx, DP_AUX_I2C_READ); >> + sp_reg_read(anx78xx, TX_P0, SP_DP_BUF_DATA0_REG, &last_block); >> + dev_dbg(dev, "last EDID block is %d\n", last_block); >> + >> + /* FIXME: Why not just cap to 3 if the reported value is >3 */ >> + if (last_block > 3) >> + last_block = 1; >> + >> + /* for every block */ >> + for (count = 0; count <= last_block; count++) { >> + switch (count) { >> + case 0: >> + case 1: >> + for (i = 0; i < 8; i++) { >> + offset = (i + count * 8) * 16; >> + if (sp_edid_read(anx78xx, offset, buf)) >> + return -1; >> + for (j = 0; j < 16; j++) >> + sp.edid_blocks[offset + j] = buf[j]; >> + } >> + break; >> + case 2: >> + case 3: >> + offset = (count == 2) ? 0x00 : 0x80; >> + for (j = 0; j < 8; j++) { >> + if (sp_seg_edid_read(anx78xx, count / 2, >> + offset)) >> + return -1; >> + offset = offset + 0x10; >> + } >> + break; >> + default: >> + break; > > Is there something which complains if you leave out the default case > statement? It's not reachable. > I left out the default case as is not reachable. >> + } >> + } >> + >> + sp_reset_aux(anx78xx); >> + >> + if (!drm_edid_block_valid(sp.edid_blocks, 0, true, NULL)) { >> + dev_err(dev, "EDID block is invalid\n"); >> + return -1; >> + } >> + >> + sp_dp_read_bytes_from_dpcd(anx78xx, DP_TEST_REQUEST, 1, &val); >> + if (val & DP_TEST_LINK_EDID_READ) { >> + dev_dbg(dev, "EDID test requested\n"); >> + val = sp_edid_block_checksum(sp.edid_blocks); >> + dev_dbg(dev, "EDID checksum is %d\n", val); >> + sp_dp_write_bytes_to_dpcd(anx78xx, DP_TEST_EDID_CHECKSUM, 1, >> + &val); >> + sp.tx_test_edid = true; >> + val = DP_TEST_EDID_CHECKSUM_WRITE; >> + sp_dp_write_bytes_to_dpcd(anx78xx, DP_TEST_RESPONSE, 1, &val); >> + } >> + >> + return 0; >> +} >> + >> +static bool sp_check_with_pre_edid(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 i; >> + u8 buf[16]; >> + bool ret = false; >> + >> + sp_tx_edid_read_initial(anx78xx); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL1_REG, 0x04); >> + sp_reg_set_bits(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, 0x03); >> + >> + if (sp_wait_aux_op_finish(anx78xx)) >> + goto return_point; >> + >> + sp_addronly_set(anx78xx, false); >> + >> + if (sp_edid_read(anx78xx, 0x70, buf)) >> + goto return_point; >> + >> + for (i = 0; i < 16; i++) { >> + if (sp.edid_blocks[0x70 + i] != buf[i]) { >> + dev_dbg(dev, "%s\n", >> + "different checksum and blocks num\n"); >> + goto return_point; >> + } >> + } > > Can you just say: > > if (memcmp(&sp.edid_blocks[0x70], buf, 16) != 0) { > dev_dbg(dev, "different checksum and blocks num\n"); > goto return_point; > } > I will change > >> + >> + if (sp_edid_read(anx78xx, 0x08, buf)) >> + goto return_point; >> + >> + for (i = 0; i < 16; i++) { >> + if (sp.edid_blocks[i + 8] != buf[i]) { >> + dev_dbg(dev, "different edid information\n"); >> + goto return_point; >> + } >> + } >> + >> + ret = true; >> +return_point: >> + sp_reset_aux(anx78xx); >> + >> + return ret; >> +} >> + > > [ snip ] > >> +static bool sp_config_video_output(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 val; >> + >> + switch (sp.tx_vo_state) { >> + default: >> + case VO_WAIT_VIDEO_STABLE: >> + sp_reg_read(anx78xx, RX_P0, SP_SYSTEM_STATUS_REG, &val); >> + if ((val & SP_TMDS_DE_DET) && (val & SP_TMDS_CLOCK_DET)) { >> + if (sp_tx_bw_lc_sel(anx78xx)) >> + return false; >> + sp_enable_video_input(anx78xx, false); >> + sp_hdmi_new_avi_int(anx78xx); >> + sp_reg_read(anx78xx, RX_P0, >> + SP_PACKET_RECEIVING_STATUS_REG, &val); >> + if (val & SP_VSI_RCVD) >> + sp_hdmi_new_vsi_int(anx78xx); >> + sp_enable_video_input(anx78xx, true); >> + sp.tx_vo_state = VO_WAIT_TX_VIDEO_STABLE; >> + } else { >> + dev_dbg(dev, "HDMI input video not stable!\n"); >> + break; >> + } >> + /* fallthrough */ >> + case VO_WAIT_TX_VIDEO_STABLE: >> + /* >> + * The flag is write clear and can be latched from last >> + * status. So the first read and write is to clear the >> + * previous status. >> + */ >> + sp_reg_read(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, &val); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, val); >> + >> + sp_reg_read(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, &val); >> + if (val & SP_CHA_STA) { >> + dev_dbg(dev, "stream clock not stable!\n"); >> + break; >> + } else { > > > No need for the else statement. Pull it in one indent level. > Ack >> + /* >> + * The flag is write clear and can be latched from >> + * last status. So the first read and write is to >> + * clear the previous status. >> + */ >> + sp_reg_read(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + &val); >> + sp_reg_write(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + val); >> + >> + sp_reg_read(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + &val); >> + if (val & SP_STRM_VALID) { >> + if (sp.tx_test_lt) >> + sp.tx_test_lt = false; >> + sp.tx_vo_state = VO_FINISH; >> + } else { >> + dev_err(dev, "video stream not valid!\n"); >> + break; >> + } >> + } >> + /* fallthrough */ >> + case VO_FINISH: >> + sp_block_power_ctrl(anx78xx, SP_TX_PWR_AUDIO, false); >> + sp_hdmi_mute_video(anx78xx, false); >> + sp_video_mute(anx78xx, false); >> + sp_show_information(anx78xx); >> + return true; >> + } Changed >> + >> + return false; >> +} >> + > > [ snip ] > >> +static void sp_config_audio(struct anx78xx *anx78xx) >> +{ >> + int i; >> + u8 val; >> + >> + sp_block_power_ctrl(anx78xx, SP_TX_PWR_AUDIO, true); >> + >> + sp_reg_read(anx78xx, TX_P0, SP_DP_MAIN_LINK_BW_SET_REG, &val); >> + if (val & SP_INITIAL_SLIM_M_AUD_SEL) >> + if (sp_calculate_audio_m_value(anx78xx)) >> + return; > > Combine these: > > if ((val & SP_INITIAL_SLIM_M_AUD_SEL) && > sp_calculate_audio_m_value(anx78xx)) > return; > Ok >> + >> + sp_reg_clear_bits(anx78xx, TX_P1, SP_AUD_INTERFACE_CTRL0_REG, >> + SP_AUD_INTERFACE_DISABLE); >> + >> + sp_reg_set_bits(anx78xx, TX_P1, SP_AUD_INTERFACE_CTRL2_REG, >> + SP_M_AUD_ADJUST_ST); >> + >> + sp_reg_read(anx78xx, RX_P0, SP_HDMI_STATUS_REG, &val); >> + if (val & SP_HDMI_AUD_LAYOUT) >> + sp_reg_set_bits(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + 5, >> + SP_I2S_CH_NUM_8 | SP_AUDIO_LAYOUT); >> + else >> + sp_reg_clear_bits(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + 5, >> + SP_I2S_CHANNEL_NUM_MASK | SP_AUDIO_LAYOUT); >> + >> + /* transfer audio channel status from HDMI Rx to Slimport Tx */ >> + for (i = 1; i <= SP_AUD_CH_STATUS_REG_NUM; i++) { >> + sp_reg_read(anx78xx, RX_P0, SP_AUD_SPDIF_CH_STATUS_BASE + i, >> + &val); >> + sp_reg_write(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + i, >> + val); >> + } > > Either this loop is off by one or the loop in sp_hdmi_audio_samplechg_int() > is off by one. Also just call that function instead of re-implimenting > it here. > Right, I'll fix that >> + >> + /* enable audio */ >> + sp_enable_audio_output(anx78xx, true); >> +} >> + >> +static bool sp_config_audio_output(struct anx78xx *anx78xx) >> +{ >> + u8 val; >> + >> + switch (sp.tx_ao_state) { >> + default: >> + case AO_INIT: >> + case AO_CTS_RCV_INT: >> + case AO_AUDIO_RCV_INT: >> + sp_reg_read(anx78xx, RX_P0, SP_HDMI_STATUS_REG, &val); >> + if (!val & SP_HDMI_MODE) { > > This is a precendence error. It should be: > Ack > if (!(val & SP_HDMI_MODE)) { > >> + sp.tx_ao_state = AO_INIT; >> + return true; >> + } >> + break; > > regards, > dan carpenter I'll wait a bit more to see if anyone else does more comments and then I'll send another version with the changes you suggested. Thanks. Regards, Enric
WARNING: multiple messages have this Message-ID (diff)
From: Enric Balletbo Serra <eballetbo@gmail.com> To: Dan Carpenter <dan.carpenter@oracle.com> Cc: Mark Rutland <mark.rutland@arm.com>, Sjoerd Simons <sjoerd.simons@collabora.co.uk>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, devel@driverdev.osuosl.org, drinkcat@chromium.org, cawa cheng <cawa.cheng@mediatek.com>, Nathan Chung <nathan.chung@mediatek.com>, Javier Martinez Canillas <javier@dowhile0.org>, Thierry Reding <treding@nvidia.com>, "devicetree@vger.kernel.org" <devicetree@vger.kernel.org>, Pawel Moll <pawel.moll@arm.com>, Ian Campbell <ijc+devicetree@hellion.org.uk>, Rob Herring <robh+dt@kernel.org>, dri-devel <dri-devel@lists.freedesktop.org>, eddie.huang@mediatek.com, cjiao@analogixsemi.com, jb.tsai@mediatek.com, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Emil Velikov <emil.l.velikov@gmail.com>, linux-kernel@vger.kernel.org, Kumar Gala <galak@codeaurora.org>, span@analogixsemi.com Subject: Re: [PATCHv6 5/5] drm: bridge: anx78xx: Add anx78xx driver support by analogix. Date: Wed, 9 Dec 2015 12:55:12 +0100 [thread overview] Message-ID: <CAFqH_51xtqzLRw30p-UfMSRe1A1zshwu9Nhg-s8xiChNCOpWmg@mail.gmail.com> (raw) In-Reply-To: <20151207080956.GB18797@mwanda> Hi Dan, Many thanks for your comments. 2015-12-07 9:09 GMT+01:00 Dan Carpenter <dan.carpenter@oracle.com>: > On Fri, Dec 04, 2015 at 09:35:07AM +0100, Enric Balletbo i Serra wrote: >> +static int sp_wait_aux_op_finish(struct anx78xx *anx78xx) >> +{ >> + u8 errcnt; >> + u8 val; >> + struct device *dev = &anx78xx->client->dev; >> + >> + errcnt = 150; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(2000, 4000); >> + } >> + >> + if (!errcnt) { > > This is off by one. It should be: > > while (--errcnt) { > ... > } > if (errcnt == 0) > return -EWHATEVER; > > Or: > > while (errcnt--) { > ... > } > if (errcnt == -1) > return -EWHATEVER; > > Also "errcnt" is a bad name, it should be retry_cnt or something (or > maybe it actually is counting errors?). Also -1 is never a correct > error code, please change all the -1 returns to something better. > Ok, I renamed to retry_cnt and changed all the -1 values to something better. >> + /* Buffer size of AUX CH is 16 */ >> + if (count > 16) >> + return -1; > > Just make a define so that you don't need to add comments about why 16 > is correct. > > if (count > SIZE_AUX_CH) > return -EINVAL; > Added a define >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(1000, 2000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP AUX Channel Control Register 2\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > Off by one again. > Ack > >> + >> + sp_reg_write(anx78xx, TX_P0, SP_AUX_ADDR_7_0_REG, SP_I2C_EXTRA_ADDR); >> + sp_tx_aux_wr(anx78xx, offset); >> + /* read 16 bytes (MOT = 1) */ >> + sp_tx_aux_rd(anx78xx, 0xf0 | DP_AUX_I2C_MOT | DP_AUX_I2C_READ); >> + >> + for (i = 0; i < 16; i++) { >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_BUF_DATA_COUNT_REG, >> + &val); >> + if (val & SP_BUF_DATA_COUNT_MASK) >> + break; >> + usleep_range(2000, 4000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP Buffer Data Count Register\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > And here. > Ack >> + errcnt = 10; >> + while (errcnt--) { >> + sp_reg_read(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, &val); >> + if (!(val & SP_AUX_EN)) >> + break; >> + usleep_range(1000, 2000); >> + } >> + >> + if (!errcnt) { >> + dev_err(dev, >> + "failed to read DP AUX Channel Control Register 2\n"); >> + sp_reset_aux(anx78xx); >> + return -1; >> + } > > Here. > Ack > >> + >> + return 0; >> +} >> + >> +static int sp_edid_block_checksum(const u8 *raw_edid) >> +{ >> + int i; >> + u8 csum = 0; >> + >> + for (i = 0; i < EDID_LENGTH; i++) >> + csum += raw_edid[i]; >> + >> + return csum; >> +} >> + >> +static int sp_tx_edid_read(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 val, last_block, offset = 0; >> + u8 buf[16]; >> + int i, j, count; >> + >> + sp_tx_edid_read_initial(anx78xx); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL1_REG, 0x04); >> + sp_reg_set_bits(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, >> + SP_AUX_EN | SP_ADDR_ONLY); >> + >> + if (sp_wait_aux_op_finish(anx78xx)) >> + return -1; >> + >> + sp_addronly_set(anx78xx, false); >> + >> + /* Read the number of blocks */ >> + sp_tx_aux_wr(anx78xx, 0x7e); >> + sp_tx_aux_rd(anx78xx, DP_AUX_I2C_READ); >> + sp_reg_read(anx78xx, TX_P0, SP_DP_BUF_DATA0_REG, &last_block); >> + dev_dbg(dev, "last EDID block is %d\n", last_block); >> + >> + /* FIXME: Why not just cap to 3 if the reported value is >3 */ >> + if (last_block > 3) >> + last_block = 1; >> + >> + /* for every block */ >> + for (count = 0; count <= last_block; count++) { >> + switch (count) { >> + case 0: >> + case 1: >> + for (i = 0; i < 8; i++) { >> + offset = (i + count * 8) * 16; >> + if (sp_edid_read(anx78xx, offset, buf)) >> + return -1; >> + for (j = 0; j < 16; j++) >> + sp.edid_blocks[offset + j] = buf[j]; >> + } >> + break; >> + case 2: >> + case 3: >> + offset = (count == 2) ? 0x00 : 0x80; >> + for (j = 0; j < 8; j++) { >> + if (sp_seg_edid_read(anx78xx, count / 2, >> + offset)) >> + return -1; >> + offset = offset + 0x10; >> + } >> + break; >> + default: >> + break; > > Is there something which complains if you leave out the default case > statement? It's not reachable. > I left out the default case as is not reachable. >> + } >> + } >> + >> + sp_reset_aux(anx78xx); >> + >> + if (!drm_edid_block_valid(sp.edid_blocks, 0, true, NULL)) { >> + dev_err(dev, "EDID block is invalid\n"); >> + return -1; >> + } >> + >> + sp_dp_read_bytes_from_dpcd(anx78xx, DP_TEST_REQUEST, 1, &val); >> + if (val & DP_TEST_LINK_EDID_READ) { >> + dev_dbg(dev, "EDID test requested\n"); >> + val = sp_edid_block_checksum(sp.edid_blocks); >> + dev_dbg(dev, "EDID checksum is %d\n", val); >> + sp_dp_write_bytes_to_dpcd(anx78xx, DP_TEST_EDID_CHECKSUM, 1, >> + &val); >> + sp.tx_test_edid = true; >> + val = DP_TEST_EDID_CHECKSUM_WRITE; >> + sp_dp_write_bytes_to_dpcd(anx78xx, DP_TEST_RESPONSE, 1, &val); >> + } >> + >> + return 0; >> +} >> + >> +static bool sp_check_with_pre_edid(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 i; >> + u8 buf[16]; >> + bool ret = false; >> + >> + sp_tx_edid_read_initial(anx78xx); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL1_REG, 0x04); >> + sp_reg_set_bits(anx78xx, TX_P0, SP_DP_AUX_CH_CTRL2_REG, 0x03); >> + >> + if (sp_wait_aux_op_finish(anx78xx)) >> + goto return_point; >> + >> + sp_addronly_set(anx78xx, false); >> + >> + if (sp_edid_read(anx78xx, 0x70, buf)) >> + goto return_point; >> + >> + for (i = 0; i < 16; i++) { >> + if (sp.edid_blocks[0x70 + i] != buf[i]) { >> + dev_dbg(dev, "%s\n", >> + "different checksum and blocks num\n"); >> + goto return_point; >> + } >> + } > > Can you just say: > > if (memcmp(&sp.edid_blocks[0x70], buf, 16) != 0) { > dev_dbg(dev, "different checksum and blocks num\n"); > goto return_point; > } > I will change > >> + >> + if (sp_edid_read(anx78xx, 0x08, buf)) >> + goto return_point; >> + >> + for (i = 0; i < 16; i++) { >> + if (sp.edid_blocks[i + 8] != buf[i]) { >> + dev_dbg(dev, "different edid information\n"); >> + goto return_point; >> + } >> + } >> + >> + ret = true; >> +return_point: >> + sp_reset_aux(anx78xx); >> + >> + return ret; >> +} >> + > > [ snip ] > >> +static bool sp_config_video_output(struct anx78xx *anx78xx) >> +{ >> + struct device *dev = &anx78xx->client->dev; >> + u8 val; >> + >> + switch (sp.tx_vo_state) { >> + default: >> + case VO_WAIT_VIDEO_STABLE: >> + sp_reg_read(anx78xx, RX_P0, SP_SYSTEM_STATUS_REG, &val); >> + if ((val & SP_TMDS_DE_DET) && (val & SP_TMDS_CLOCK_DET)) { >> + if (sp_tx_bw_lc_sel(anx78xx)) >> + return false; >> + sp_enable_video_input(anx78xx, false); >> + sp_hdmi_new_avi_int(anx78xx); >> + sp_reg_read(anx78xx, RX_P0, >> + SP_PACKET_RECEIVING_STATUS_REG, &val); >> + if (val & SP_VSI_RCVD) >> + sp_hdmi_new_vsi_int(anx78xx); >> + sp_enable_video_input(anx78xx, true); >> + sp.tx_vo_state = VO_WAIT_TX_VIDEO_STABLE; >> + } else { >> + dev_dbg(dev, "HDMI input video not stable!\n"); >> + break; >> + } >> + /* fallthrough */ >> + case VO_WAIT_TX_VIDEO_STABLE: >> + /* >> + * The flag is write clear and can be latched from last >> + * status. So the first read and write is to clear the >> + * previous status. >> + */ >> + sp_reg_read(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, &val); >> + sp_reg_write(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, val); >> + >> + sp_reg_read(anx78xx, TX_P0, SP_DP_SYSTEM_CTRL_BASE + 2, &val); >> + if (val & SP_CHA_STA) { >> + dev_dbg(dev, "stream clock not stable!\n"); >> + break; >> + } else { > > > No need for the else statement. Pull it in one indent level. > Ack >> + /* >> + * The flag is write clear and can be latched from >> + * last status. So the first read and write is to >> + * clear the previous status. >> + */ >> + sp_reg_read(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + &val); >> + sp_reg_write(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + val); >> + >> + sp_reg_read(anx78xx, TX_P0, >> + SP_DP_SYSTEM_CTRL_BASE + 3, >> + &val); >> + if (val & SP_STRM_VALID) { >> + if (sp.tx_test_lt) >> + sp.tx_test_lt = false; >> + sp.tx_vo_state = VO_FINISH; >> + } else { >> + dev_err(dev, "video stream not valid!\n"); >> + break; >> + } >> + } >> + /* fallthrough */ >> + case VO_FINISH: >> + sp_block_power_ctrl(anx78xx, SP_TX_PWR_AUDIO, false); >> + sp_hdmi_mute_video(anx78xx, false); >> + sp_video_mute(anx78xx, false); >> + sp_show_information(anx78xx); >> + return true; >> + } Changed >> + >> + return false; >> +} >> + > > [ snip ] > >> +static void sp_config_audio(struct anx78xx *anx78xx) >> +{ >> + int i; >> + u8 val; >> + >> + sp_block_power_ctrl(anx78xx, SP_TX_PWR_AUDIO, true); >> + >> + sp_reg_read(anx78xx, TX_P0, SP_DP_MAIN_LINK_BW_SET_REG, &val); >> + if (val & SP_INITIAL_SLIM_M_AUD_SEL) >> + if (sp_calculate_audio_m_value(anx78xx)) >> + return; > > Combine these: > > if ((val & SP_INITIAL_SLIM_M_AUD_SEL) && > sp_calculate_audio_m_value(anx78xx)) > return; > Ok >> + >> + sp_reg_clear_bits(anx78xx, TX_P1, SP_AUD_INTERFACE_CTRL0_REG, >> + SP_AUD_INTERFACE_DISABLE); >> + >> + sp_reg_set_bits(anx78xx, TX_P1, SP_AUD_INTERFACE_CTRL2_REG, >> + SP_M_AUD_ADJUST_ST); >> + >> + sp_reg_read(anx78xx, RX_P0, SP_HDMI_STATUS_REG, &val); >> + if (val & SP_HDMI_AUD_LAYOUT) >> + sp_reg_set_bits(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + 5, >> + SP_I2S_CH_NUM_8 | SP_AUDIO_LAYOUT); >> + else >> + sp_reg_clear_bits(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + 5, >> + SP_I2S_CHANNEL_NUM_MASK | SP_AUDIO_LAYOUT); >> + >> + /* transfer audio channel status from HDMI Rx to Slimport Tx */ >> + for (i = 1; i <= SP_AUD_CH_STATUS_REG_NUM; i++) { >> + sp_reg_read(anx78xx, RX_P0, SP_AUD_SPDIF_CH_STATUS_BASE + i, >> + &val); >> + sp_reg_write(anx78xx, TX_P2, SP_AUD_CH_STATUS_BASE + i, >> + val); >> + } > > Either this loop is off by one or the loop in sp_hdmi_audio_samplechg_int() > is off by one. Also just call that function instead of re-implimenting > it here. > Right, I'll fix that >> + >> + /* enable audio */ >> + sp_enable_audio_output(anx78xx, true); >> +} >> + >> +static bool sp_config_audio_output(struct anx78xx *anx78xx) >> +{ >> + u8 val; >> + >> + switch (sp.tx_ao_state) { >> + default: >> + case AO_INIT: >> + case AO_CTS_RCV_INT: >> + case AO_AUDIO_RCV_INT: >> + sp_reg_read(anx78xx, RX_P0, SP_HDMI_STATUS_REG, &val); >> + if (!val & SP_HDMI_MODE) { > > This is a precendence error. It should be: > Ack > if (!(val & SP_HDMI_MODE)) { > >> + sp.tx_ao_state = AO_INIT; >> + return true; >> + } >> + break; > > regards, > dan carpenter I'll wait a bit more to see if anyone else does more comments and then I'll send another version with the changes you suggested. Thanks. Regards, Enric _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2015-12-09 11:55 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-12-04 8:35 [PATCHv6 0/5] Add initial support for slimport anx78xx Enric Balletbo i Serra 2015-12-04 8:35 ` Enric Balletbo i Serra 2015-12-04 8:35 ` [PATCHv6 1/5] drm/dp: add DPCD definitions from DP 1.1 Enric Balletbo i Serra 2015-12-04 8:35 ` Enric Balletbo i Serra 2015-12-04 8:35 ` [PATCHv6 2/5] hdmi: added functions for MPEG InfoFrames Enric Balletbo i Serra 2015-12-04 8:35 ` Enric Balletbo i Serra 2015-12-04 8:35 ` [PATCHv6 3/5] of: Add vendor prefix for Analogix Semiconductor, Inc Enric Balletbo i Serra 2015-12-04 8:35 ` [PATCHv6 4/5] devicetree: Add new ANX7814 SlimPort transmitter binding Enric Balletbo i Serra 2015-12-04 8:35 ` Enric Balletbo i Serra 2015-12-04 16:13 ` Rob Herring 2015-12-04 16:13 ` Rob Herring 2015-12-04 8:35 ` [PATCHv6 5/5] drm: bridge: anx78xx: Add anx78xx driver support by analogix Enric Balletbo i Serra 2015-12-04 8:35 ` Enric Balletbo i Serra 2015-12-07 8:09 ` Dan Carpenter 2015-12-07 8:09 ` Dan Carpenter 2015-12-09 11:55 ` Enric Balletbo Serra [this message] 2015-12-09 11:55 ` Enric Balletbo Serra
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CAFqH_51xtqzLRw30p-UfMSRe1A1zshwu9Nhg-s8xiChNCOpWmg@mail.gmail.com \ --to=eballetbo@gmail.com \ --cc=airlied@linux.ie \ --cc=cawa.cheng@mediatek.com \ --cc=cjiao@analogixsemi.com \ --cc=dan.carpenter@oracle.com \ --cc=devel@driverdev.osuosl.org \ --cc=devicetree@vger.kernel.org \ --cc=djkurtz@chromium.org \ --cc=dri-devel@lists.freedesktop.org \ --cc=drinkcat@chromium.org \ --cc=eddie.huang@mediatek.com \ --cc=emil.l.velikov@gmail.com \ --cc=galak@codeaurora.org \ --cc=gregkh@linuxfoundation.org \ --cc=ijc+devicetree@hellion.org.uk \ --cc=javier@dowhile0.org \ --cc=jb.tsai@mediatek.com \ --cc=laurent.pinchart@ideasonboard.com \ --cc=linux-kernel@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=nathan.chung@mediatek.com \ --cc=pawel.moll@arm.com \ --cc=robh+dt@kernel.org \ --cc=sjoerd.simons@collabora.co.uk \ --cc=span@analogixsemi.com \ --cc=treding@nvidia.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.